[R] do.call environment misunderstanding

Dan Murphy chiefmurphy at gmail.com
Tue Jun 25 17:56:04 CEST 2013


So the trick is to put the function f into e and define its environment to be e:
> e <- new.env()
> e$f <- function() x^2
> environment(e$f) <- e
> e$x <- 2
> do.call("f", list(), envir = e)
[1] 4

Thanks, Duncan.

On Tue, Jun 25, 2013 at 6:49 AM, Duncan Murdoch
<murdoch.duncan at gmail.com> wrote:
> On 25/06/2013 9:32 AM, Dan Murphy wrote:
>>
>> I am having difficulty understanding the envir argument of do.call.
>> The help page says
>>
>> envir  an environment within which to evaluate the call.
>>
>> so I thought that in the following toy example x would be found in the
>> environment e and f would return 4 via do.call:
>>
>> > e <- new.env()
>> > e$x <- 2
>> > f <- function() x^2
>> > do.call(f, list(), envir = e)
>> Error in (function ()  : object 'x' not found
>>
>> Thanks in advance for clarifying my misunderstanding.
>
>
> do.call will construct the expression f(), then evaluate it in e. It will
> try to look up f there, and not finding it, will go to the parent
> environment and find it.
>
> When evaluating the function, the environment in which it was evaluated is
> used for looking up arguments, but f() has none, so e is not used at all.  R
> will use the environment attached to f, which is the global environment,
> since you created f by evaluating its definition there.
>
> To get what you want, you could use the sequence
>
>
> e <- new.env()
> e$x <- 2
> f <- function() x^2
> environment(f) <- e
> f()
>
> An alternative way to do the 3rd and 4th lines is
>
> f <- with(e, function() x^2)
>
> because that would evaluate the creation of f within e.
>
> A third approach (which might be the nicest one, depending on what else you
> are doing) is never to name e:
>
> f <- local({
>   x <- 2
>   function() x^2
> })
>
> Duncan Murdoch



More information about the R-help mailing list