[R] substitute in a named expression
Gabor Grothendieck
ggrothendieck at gmail.com
Thu Jun 23 00:47:07 CEST 2005
On 6/22/05, Søren Højsgaard <Soren.Hojsgaard at agrsci.dk> wrote:
> I have a 'named expression' like
> expr <- expression(rep(1,d))
> and would like to replace the argument d with say 5 without actually evaluating the expression. So I try substitute(expr, list(d=5)) in which case R simply returns expr which when I 'evaluate' it gives
> eval(expr)
> Error in rep.default(1, d) : invalid number of copies in rep()
>
> I've looked at ?substitute and ?expression (and other places) for ideas, but - well I guess there are some details which I haven't quite understood. Can anyone point me in the right direction?
Try this:
eval(substitute(substitute(qq, list(d=5)), list(qq = expr[[1]])))
This aspect of R drove me crazy some time ago but Tony Plate finally figured
it out and discussed it some time back:
http://tolstoy.newcastle.edu.au/R/help/04/03/1247.html
There is also a handy utility routine, esub, defined there.
The key points are:
- substitute won't go inside expressions but it will go inside call objects.
In this case your expr is an expression but expr[[1]] is a call object with
the desired contents. Note that quote will return a call
object so you can avoid the [[1]] if you define expr as cl <- quote(rep(1,d))
i.e.
cl <- quote(rep(1,d))
eval(substitute(substitute(cl, list(d=5)), list(cl = cl)))
- substitute autoquotes anything inside it so one must substitute in
the first argument to the inner substitute using a second outer substitute.
That is, the outer substitute substitutes expr[[1]] (which is evaluated) into
the first argument of the inner substitute.
- the outer substitute wraps the result of the inner one in a call so we must
perform an eval to get what is within the call. This part is explained in
?substitute
Sorry if this is complicated but that seems to be how it works. Using
the esub function defined in the link above you can simplify it substantially
like this:
esub(cl, list(d=5))
# or
esub(expr[[1]], list(d=5))
More information about the R-help
mailing list