2012-03-02 5 views
9

Estoy buscando una forma de crear una expresión que sea el producto de dos expresiones dadas. Por ejemplo, supongamos que tengoManipulación de expresiones en R

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

Ahora quiero crear mediante programación la expresión (e1)*(e2):

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

Antecedentes Estoy escribiendo una función de ajuste del modelo. El modelo tiene dos piezas definidas por el usuario. Necesito poder "manejarlos" por separado, y luego crear una expresión combinada y "manejarla" como un modelo. "Manejo" implica tomar derivados numéricos, y la función deriv quiere expresiones como una entrada.

+0

Como nota al margen: si se encuentra en una situación similar pero no requiere una 'expresión' para una salida, cree funciones en su lugar y use 'cuerpo' para modificar el contenido de la función. –

Respuesta

5

que no se ocupan de esto muy a menudo, pero algo como esto parece estar funcionando

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

Gracias, esto es lo que necesitaba. Los paréntesis en '(e1) * (e2)' ni siquiera son necesarios, R es lo suficientemente inteligente como para ponerlos. – Aniko

+0

¡Tienes razón! Voy a editar eso en la respuesta. – Dason

5

Prueba esto:

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

¡Gracias! Acepté la respuesta de Dason, que es esencialmente la misma idea, porque respondió la pregunta exacta, pero esta respuesta me proporcionó información adicional. – Aniko

2

Es algo excesivo en su caso, pero el paquete Ryacas puede ser amable por realizar manipulaciones simbólicas más complicadas de este tipo:

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

A lso, en lugar de utilizar substitute(), se puede construir la misma expresión en la base de R como esto:

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

Nota explicativa: Un aspecto confuso al principio de tratar con expression objetos es que son muy listas del lenguaje objetos, incluso cuando (como suele ser el caso) esas listas contienen solo un objeto. Por ejemplo, en su pregunta, tanto e1 como e2 son listas de longitud 1 que contienen un solo objeto call cada una.

Trabajando desde adentro hacia afuera, el código anterior:

  1. Extractos los dos objetos usando call[[1]]
  2. Usos as.call() que construye una nueva llamada que es el producto de los dos objetos call.
  3. Finalmente, envuelve la copia de seguridad resultante call como el objeto expression que desea.
+0

Sí, traté de jugar con la expresión como una lista, pero no pude hacerlo funcionar. No es de extrañar, esto es complicado. – Aniko

+0

Sin dudas. Solo comienza a tener mucho sentido para mí después de ~ 5 años de trabajo con el lenguaje regularmente. Buena suerte construyendo tu función. –