[R] Problem with do.call().

peter dalgaard pdalgd at gmail.com
Fri Mar 28 13:34:07 CET 2014


On 28 Mar 2014, at 02:37 , Rolf Turner <r.turner at auckland.ac.nz> wrote:
>> 
>> So there you are.  Feel enlightened?
> 
> Somewhat, actually, but not to such an extent as to have reached nirvana.  "Promises" blow me away.
> 
>> 
>> Here's the most useful part of the post:  to get what you want, use
>> 
>> do.call(plot, list(x=x, y=y, xlab="x", ylab="y"))
> 
> Yes.  That's effectively what I wound up doing --- in a slightly more complicated context.
> 
> Thomas's idea is sexier, but I of course understand even less than you profess to do.

Well, let me try (famous last words, I know)

x <- 1
do.call("plot", list(x=x))

is equivalent to 

plot(x=1)

because the list argument is a list with one element, called 'x' and having the value '1'. do.call is not going out to look for the difference between that and, say, 

y <- 1
l <- list(x=y)
do.call("plot", l)

The thing that is going on inside do.call is that first we construct the call, effectively using

as.call(c(as.name("plot"), list(x=x)))

which you can verify results in the unevalued expression

plot(x = 1)

Then, the expression is evaluated, and at this stage, plot obviously has no idea that the argument 1 was called x at some earlier stage.

Thomas' trick amounts to

as.call(c(as.name("plot"), list(x=quote(x))))

which is

plot(x = x)

which obviously does the usual thing when evaluated. The main part of the magic lies in the conversion of lists to call objects and vice versa.

(One curiosity: 

> do.call(quote(plot),list(quote(x)))
Error in do.call(quote(plot), list(quote(x))) : 
  'what' must be a character string or a function

which sees a bit overzealous. I see no reason that it shouldn't work.)
-- 
Peter Dalgaard, Professor
Center for Statistics, Copenhagen Business School
Solbjerg Plads 3, 2000 Frederiksberg, Denmark
Phone: (+45)38153501
Email: pd.mes at cbs.dk  Priv: PDalgd at gmail.com




More information about the R-help mailing list