[R] Scope and apply-type functions

Bert Gunter gunter.berton at gene.com
Thu Mar 17 22:07:46 CET 2011


Try this:

lapply(1:5,function(i){i;function()i})[[2]]()

or

 lapply(1:5,function(i){i;function(j=i) j } )[[2]]()


## both give 2

Now try:

lapply(1:5,function(i){function(j=i) j } )[[2]]()

## gives 5 !


The problem is that if you do:

 lapply(1:5,function(h){function(h)h)

what you get is a list of functions of the form function(h)h , where the
The "h" in this function has nothing to do with the index "h" in the
lapply statement, which no longer exists. So the result is an error
message saying it can't find h.

The top 2 versions specifically put the value of i at the time the ith
function is defined into the function environment, so they exist after
the lapply call is finished.

The 3rd version obviously uses the value of i at the conclusion of the
lapply call when the list of functions is returned from the lapply
call and they need to find the value of i for their environments.

In general, the scoping with lapply gets complicated and, iirc, the
experts have said is nonstandard (Experts: please correct if wrong).
So the best advice is to try to avoid constructs like this if
possible.

-- Bert


On Thu, Mar 17, 2011 at 11:01 AM, jamie.f.olson
<inspired2apathy at gmail.com> wrote:
> So, I've been confused by this for a while.  If I want to create functions in
> an apply, it only uses the desired value for the variable if I create a new
> local variable:
>
>> lapply(1:5,function(h){k=h;function(){k}})[[1]]()
> [1] 1
>> lapply(1:5,function(k){function(){k}})[[1]]()
> [1] 5
>>
>
> Normally, a function will use values for a variable if the variable is local
> to the definition of the function:
>
>> a = function(x){function(){x}}
>> a(5)
> function(){x}
>
>> a(5)()
> [1] 5
>> a(6)()
> [1] 6
>
>
> So why doesn't this work for apply?  Does apply work more like loops, with a
> shared variable that changes values so that the first function defined
> actually uses the last value of the variable?
>
>> a = list();for (k in 1:5){a = c(a,function(){k})}
>> a[[1]]()
> [1] 5
>>
>
>
> Or is there something else entirely?
>
> --
> View this message in context: http://r.789695.n4.nabble.com/Scope-and-apply-type-functions-tp3385230p3385230.html
> Sent from the R help mailing list archive at Nabble.com.
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>



More information about the R-help mailing list