[R] Problem with do.call().
Duncan Murdoch
murdoch.duncan at gmail.com
Fri Mar 28 13:09:03 CET 2014
On 28/03/2014, 2:04 AM, Philippe Grosjean wrote:
> On 28 Mar 2014, at 00:57, Duncan Murdoch <murdoch.duncan at gmail.com> wrote:
>
>> On 27/03/2014, 7:38 PM, Thomas Lumley wrote:
>>> You get what you wanted from
>>>
>>> do.call(plot,list(x=quote(x),y=quote(y)))
>>>
>>> By the time do.call() gets the arguments it doesn't know how y was
>>> originally computed, just what values it has.
>>
>> This works, but it doesn't make sense to me. The arguments end up with the expressions x and y, but why are they evaluated in the right place? Quote doesn't bind an environment to its expressions, does it? How does plot() know where to evaluate them?
>>
>> Duncan Murdoch
>>
> I am puzzled here… Isn't it the same when you write plot(x = x, y = y)? You don't tell the environment for your 'x' and 'y' expressions, isn't it? And they are defined from the context the function call and definition. You do the same with the env= argument of do.call() which is equal to parent.frame() by default. As far as I understand, it is behaving similarly. I have tried a few "risky" situations:
In that case the environment is the evaluation environment for the
plot() call.
I'm in a rush right now, so I haven't analyzed all of these examples,
but I have one more comment down below.
> 1) S3 dispatch:
> ## do.call() with quote() inside S3 methods
> ## Trying to be silly by defining x and y inside the generic too to make sure do.call() isn't confused
> myPlot <- function (x, y, ...) {
> x <- 101:110
> y <- rep(1, 10)
> UseMethod("myPlot")
> }
>
> ## A method that uses plot() directly
> myPlot.anObj1 <- function (x, y, ...)
> plot(x = x, y = y)
> x <- structure(1:10, class = "anObj1")
> y <- (x - 5.5)^2
> myPlot(x = x, y = y) # right
>
> ## A method that uses do.call() with quote()
> myPlot.anObj2 <- function (x, y, ...)
> do.call(plot, list(x = quote(x), y = quote(y)))
> x <- structure(1:10, class = "anObj2")
> myPlot(x = x, y = y) # same result
>
> ## A dispatch to the default method
> myPlot.default <- function (x, y, ...)
> do.call(plot, list(x = quote(x), y = quote(y)))
> x <- 1:10
> myPlot(x = x, y = y) # same result
>
> This seems to give the same thing.
>
> 2) A really crazy and tortuous closure where I try to confuse do.call() with lexical scoping and all the stuff:
>
> ## This one uses plot() directly
> makePlotFun1 <- function () {
> x <- 1:10
> y <- (x - 5.5)^2
> Y <- y
> ## If I use y directly as default value for argument y= in the next instruction
> ## I got a "promise already under evaluation" error!
> function (x, y = Y) plot(x = x, y = y)
> }
>
> ## This one uses do.call(plot, ….)
> makePlotFun2 <- function () {
> x <- 1:10
> y <- (x - 5.5)^2
> Y <- y ## Same remark as for makePlotFun1()
> function (x, y = Y) {
> do.call(plot, list(x = quote(x), y = quote(y)))
> }
> }
>
> ## Different x and y values in .GlobalEnv
> x <- 101:110
> y <- rep(1, 10)
>
> myPlotFun1 <- makePlotFun1()
> myPlotFun1(x = x, y = y)
> ## and...
> myPlotFun1(x = x) # It uses y from the closure. It's fine.
>
> ## Now, using do.call()
> myPlotFun2 <- makePlotFun2()
> myPlotFun2(x = x, y = y)
> ## and...
> myPlotFun2(x = x) # Same result
>
>
> You are probably right, but I cannot think of a situation where do.call(plot, list(x = quote(x), y = quote(y)) do not give the same result as list(x = x, y = y). Have you an example?
Rolf's example is one, e.g.
x <- 1:10
y <- x^2
plot(x,y) # gets nice xlab and ylab
do.call(plot, list(x=x, y=y)) # ugly xlab and ylab
do.call(plot, list(x=quote(x), y=quote(y)) # nice xlab and ylab
Duncan Murdoch
> Best,
>
> Philippe
>
>
>
>>
>>>
>>> -thomas
>>>
>>>
>>> On Thu, Mar 27, 2014 at 6:17 PM, Rolf Turner <r.turner at auckland.ac.nz>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,list(x=x,y=y))
>>>>
>>>> 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.
>>>>
>>>> cheers,
>>>>
>>>> Rolf Turner
>>>>
>>>> ______________________________________________
>>>> R-help at 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.
>>>>
>>>
>>>
>>>
>>
>> ______________________________________________
>> R-help at 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.
>>
>
More information about the R-help
mailing list