[R] Problem with do.call().
Duncan Murdoch
murdoch.duncan at gmail.com
Fri Mar 28 00:49:06 CET 2014
On 27/03/2014, 7:17 PM, Rolf Turner wrote:
>
>
> I was under the impression that
>
> do.call(foo,list(x=x,y=y))
>
> should yield the same result as
>
> foo(x,y).
>
> However if I do
>
> x <- 1:10
> y <- (x-5.5)^2
> do.call(plot)
>
> I get the expected plot but with the y-values (surrounded by c()) being
> printed (vertically) in the left-hand margin of the plot.
>
> The help for do.call() says:
>
>> The behavior of some functions, such as substitute, will not be the
>> same for functions evaluated using do.call as if they were evaluated
>> from the interpreter. The precise semantics are currently undefined and
>> subject to change.
>
> Am I being bitten by an instance of this phenomenon? Seems strange.
>
> I would be grateful for enlightenment.
Yes, you are being bitten that way.
Here are some details. Enlightenment? Probably not...
When you call a function as plot(x,y), R constructs "promises" for the
arguments: these are objects that contain the expressions x and y,
associated with the first two arguments to plot (which happen to be
named x and y as well). When the plot function makes use of its
arguments the first time, the promises are evaluated, which means that
the expressions are evaluated and the values are stored in the promises.
Later evaluations just retrieve that stored value.
When plot() builds its labels, it uses substitute() on the argument.
When substitute is given a promise, it returns the expression associated
with it, which plot converts to a string: so the labels on plot(x, y)
end up as "x" and "y".
That's the normal way things happen.
When you call do.call() instead, it evaluates its "args" argument, which
is list(x=x,y=y) in your example. That gives it a named list with names
"x" and "y". The values in those slots are the evaluated values of x
and y. It passes these to plot(), associating those values with the
arguments named x and y. It doesn't ever construct promises like in the
usual mechanism, so substitute() can't find an expression to convert
into a label. It just gives the value, which plot converts to a string.
So there you are. Feel enlightened?
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"))
Duncan Murdoch
More information about the R-help
mailing list