[R] do.call environment misunderstanding

Dan Murphy chiefmurphy at gmail.com
Wed Jun 26 03:05:10 CEST 2013


My problem is to evaluate a function/model whose definition and
parameters (I'll put x into the arguments) and other data are saved by
someone else in an Rdata file, but I don't know the function name,
definition or data. Nevertheless, I need to save whatever functional
values/model solutions are so determined and to compare and contrast
solutions of same and similar problems over time. Environments seemed
to hold promise, but understanding the relationship between f and e
was my first hurdle. Thanks again.

On Tue, Jun 25, 2013 at 9:54 AM, Duncan Murdoch
<murdoch.duncan at gmail.com> wrote:
> 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