do.call environment misunderstanding
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