[R] Problem with do.call().

Philippe Grosjean phgrosjean at sciviews.org
Fri Mar 28 07:04:56 CET 2014


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:

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?

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