On 28/03/14 12:49, Duncan Murdoch wrote:
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?
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.
Thanks.
cheers,
Rolf
______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.