Re: [R] substitute in a named expression

From: Peter Dalgaard <>
Date: Thu 23 Jun 2005 - 09:09:45 EST

Gabor Grothendieck <> writes:

> On 6/22/05, Søren Højsgaard <> 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:
> 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))

Yes, substitute() is a bass-ackward design and the automatic quoting of the first arg is a pain. It would have been much cleaner if standard semantics were used and you'd just quote() the argument when needed.

Your explanation of

> eval(substitute(substitute(qq, list(d=5)), list(qq = expr[[1]])))

is a tad long-winded though.

What happens is that the inner unevaluated

substitute(qq, list(d=5))

gets the qq replaced by the value of expr[[1]]. In casu it becomes


this then needs to be evaluated, yielding


   O__  ---- Peter Dalgaard             Øster Farimagsgade 5, Entr.B
  c/ /'_ --- Dept. of Biostatistics     PO Box 2099, 1014 Cph. K
 (*) \(*) -- University of Copenhagen   Denmark          Ph: (+45) 35327918
~~~~~~~~~~ - (                  FAX: (+45) 35327907

______________________________________________ mailing list
PLEASE do read the posting guide!
Received on Thu Jun 23 09:14:45 2005

This archive was generated by hypermail 2.1.8 : Fri 03 Mar 2006 - 03:32:57 EST