[R] returning functions inside lapply

Duncan Murdoch murdoch.duncan at gmail.com
Wed Apr 25 00:37:23 CEST 2012


On 12-04-24 5:13 PM, Ali Tofigh wrote:
> On Tue, Apr 24, 2012 at 16:57, Duncan Murdoch<murdoch.duncan at gmail.com>  wrote:
>>> I thought that
>>> lapply calls f three times and returns a list with whatever f
>>> returned. Is this not so?
>>
>> That is so.  In each case, f creates a function that looks in its enclosing
>> environment for the variable x to be returned.
>>
>> That enclosing environment is the evaluation frame of f, where x is the
>> argument being passed.
>>
>> But x is never used in evaluating f, so the promise to evaluate x is never
>> forced until you finally call one of those functions.
>>
>> That means x will refer to some internal variable in lapply (which sapply
>> calls).  You'll have 3 different promises to evaluate it, but they all
>> evaluate to the same value.
>
> Thank you Duncan for you reply! However, I'm not sure I understand
> this last explanation. This is what I think you mean lapply does.
> Pleas correct me if I'm wrong.
>
> 1) lapply uses the same variable name as the argument in my function
> (in this case 'x')

No, lapply can use any name it likes, or no name at all (e.g. just an 
expression like 1+y).

> 2) lapply uses this 'x' variable to set up a bunch of unevaluated calls

No, lapply calls f a bunch of times, passing this expression each time.

> 3) finally, lapply evaluates all the calls. but at this point,
> lapply's 'x' variable is set to the last element of the list that was
> passed to it and all the unevaluated calls will now use this value as
> their 'x'?

When lapply evaluates f, it produces a function that refers to the local 
variable x in each evaluation frame.  That's a different variable each 
time, but in all cases it's a promise to evaluate the expression that 
lapply passed in.  So if lapply passed 1+y as the expression, x becomes 
a promise to evaluate 1+y in lapply's evaluation frame.

Since you don't call any of those functions until after lapply is done, 
its evaluation frame will remain.  It's hard to get to it, but each of 
those promises references it.

When you finally evaluate x in one of those functions, it goes and 
evaluates 1+y in the lapply frame (or whatever the expression was). 
That evaluates to 3.  It could have evaluated to 17 if lapply had done 
something stupid like setting y to 16 after calling f in the loop, but R 
functions never do stupid things, so you don't need to worry about that.

Duncan Murdoch



More information about the R-help mailing list