Manipulating expressions in R
Asked Answered
S

3

9

I am looking for a way to create an expression that is the product of two given expressions. For example, suppose I have

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

Now I want to create programatically the expression (e1)*(e2):

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

Background I am writing a model fitting function. The model has two pieces that are user-defined. I need to be able to "handle" them separately, and then create a combined expression and "handle" it as one model. "Handling" involves taking numeric derivatives, and the deriv function wants expressions as an input.

Stickinthemud answered 2/3, 2012 at 16:31 Comment(1)
As a side note: if you are in a similar situation but do not require an expression for an output, create functions instead and use body to modify the contents of the function.Rocray
P
5

I don't deal with this too often but something like this seems to be working

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))
Philipphilipa answered 2/3, 2012 at 16:48 Comment(1)
Thanks, this is what I needed. The parentheses in (e1)*(e2) are not even needed - R is smart enough to put them in.Stickinthemud
L
5

Try this:

e1 <- quote(a+b*x)   # or expression(*)[[1]]
e2 <- quote(c+d*x)
substitute(e1 * e2, list(e1=e1, e2=e2))
Leith answered 2/3, 2012 at 16:46 Comment(1)
Thanks! I accepted Dason's answer, which is essentially the same idea, because he answered the exact question asked, but this answer provided additional insight.Stickinthemud
P
5

I don't deal with this too often but something like this seems to be working

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))
Philipphilipa answered 2/3, 2012 at 16:48 Comment(1)
Thanks, this is what I needed. The parentheses in (e1)*(e2) are not even needed - R is smart enough to put them in.Stickinthemud
M
2

It's probably overkill in your case, but the Ryacas package can be nice for performing more complicated symbolic manipulations of this sort:

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

Also, instead of using substitute(), you can construct the same expression in base R like this:

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

Explanatory note: One initially confusing aspect of dealing with expression objects is that they are really lists of language objects -- even when (as is often the case) those lists contain just one object. For example, in your question, both e1 and e2 are length 1 lists containing a single call object each.

Working from the inside out, the code above:

  1. Extracts the two call objects using [[1]]
  2. Uses as.call() to constructs a new call that is the product of the two call objects.
  3. Finally, wraps the resultant call back up as the expression object that you want.
Maitland answered 2/3, 2012 at 17:11 Comment(2)
Yeah, I tried playing with the expression as a list, but could not make it work. No wonder, this is tricky.Stickinthemud
No doubt. It's only starting to make much sense to me after ~5 years of working with the language on the pretty regular basis. Best of luck constructing your function.Harlequinade

© 2022 - 2024 — McMap. All rights reserved.