2012-03-02 19 views
9

Szukam sposobu na tworzenie wyrażenia, które jest wynikiem dwóch określonych wyrażeń. Na przykład załóżmy, że mamManipulowanie wyrażeniami w R

e1 <- expression(a+b*x) 
e2 <- expression(c+d*x) 

Teraz chcę utworzyć programowo ekspresję (e1)*(e2):

expression((a+b*x)*(c+d*x)) 

Tło Piszę funkcję dopasowania modelu. Model ma dwie części zdefiniowane przez użytkownika. Muszę umieć "obsłużyć" je osobno, a następnie utworzyć połączone wyrażenie i "obsłużyć" je jako jeden model. "Obsługa" obejmuje przyjmowanie pochodnych numerycznych, a funkcja deriv żąda wyrażeń jako danych wejściowych.

+0

Na marginesie: jeśli znajdujesz się w podobnej sytuacji, ale nie potrzebujesz "wyrażenia" dla wyjścia, utwórz funkcje zamiast niego i użyj "treści", aby zmodyfikować zawartość funkcji. –

Odpowiedz

5

nie radzić sobie z tym zbyt często, ale coś takiego wydaje się działać

e1 <- expression(a + b*x) 
e2 <- expression(c + d*x) 
substitute(expression(e1*e2), list(e1 = e1[[1]], e2 = e2[[1]])) 
# expression((a + b * x) * (c + d * x)) 
+0

Dzięki, to jest to, czego potrzebowałem. Nawiasy w '(e1) * (e2)' nie są nawet potrzebne - R jest na tyle sprytny, aby je wprowadzić. – Aniko

+0

Masz rację! Zmienię to w odpowiedź. – Dason

5

Spróbuj tego:

e1 <- quote(a+b*x) # or expression(*)[[1]] 
e2 <- quote(c+d*x) 
substitute(e1 * e2, list(e1=e1, e2=e2)) 
+0

Dzięki! Przyjąłem odpowiedź Dasona, która jest zasadniczo tym samym pomysłem, ponieważ odpowiedział dokładnie na zadane pytanie, ale ta odpowiedź dostarczyła dodatkowego wglądu. – Aniko

2

To chyba przesada w twoim przypadku, ale pakiet Ryacas puszka być miłym w wykonywaniu bardziej skomplikowanych symbolicznych manipulacji tego rodzaju:

library(Ryacas) 
yacas(expression(e1*e2))$text 
# expression((a + b * x) * (c + d * x)) 

A LSO, zamiast korzystania substitute() można skonstruować ten sam wyraz w podstawowej R takiego:

as.expression(as.call(list(as.symbol("*"), e1[[1]], e2[[1]]))) 
# expression((a + b * x) * (c + d * x)) 

Objaśnienia: One początkowo mylące aspekt czynienia z expression obiektów jest to, że są one naprawdę listy języka obiekty - nawet gdy (jak to często bywa) te listy zawierają tylko jeden obiekt. Na przykład w pytaniu oba e1 i e2 są listami długości 1 zawierającymi pojedynczy obiekt call.

Praca od środka na zewnątrz, powyższy kod:

  1. wyodrębnia dwa call obiekty za pomocą [[1]]
  2. Używa as.call() do konstruuje nowe połączenie, które jest iloczynem dwóch call obiektów.
  3. Na koniec zwija wynikowy obiekt call jako żądany obiekt .
+0

Tak, próbowałem grać z wyrażeniem jako listą, ale nie mogłem sprawić, żeby działało. Nic dziwnego, to jest trudne. – Aniko

+0

Bez wątpienia. To zaczyna mieć dla mnie sens dopiero po ~ 5 latach pracy z językiem na całkiem regularnych zasadach. Powodzenia w budowaniu swojej funkcji. –