[R] do.call environment misunderstanding

Duncan Murdoch murdoch.duncan at gmail.com
Tue Jun 25 18:54:14 CEST 2013


On 25/06/2013 11:56 AM, Dan Murphy wrote:
> So the trick is to put the function f into e and define its environment to be e:

Putting f into e, and defining the environment of f to be e solve 
different problems.  Your toy example has both problems so it's a 
reasonable solution there, but most real examples don't, so I wouldn't 
think of those two solutions as being connected.

Duncan Murdoch

> > 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