R anonymous function: commit variables by value

I have defined a list of anonymous functions that use a variable defined in the outer scope.

funclist <- list() for(i in 1:5) { funclist[[i]] <- function(x) print(i) } funclist[[1]]('foo') 

Output:

 [1] 5 

It seems that i is being fixed by reference. I would like it to be captured by the value, i.e. The exit should be

 [1] 1 

Is there a way to tell the R, to capture i by value, not by reference?

+4
source share
2 answers

When you run a for loop, this creates a variable in the environment in which the loop is running, and the functions created in the loop also run from that environment. Therefore, whenever you run functions created in this way that use the index value from the loop, they only have access to the final value, and only as long as this varaible remains (try rm(i) and try to entertain one of the functions to the list).

What you need to do is bind the index value to a function in their own environment. lapply will do this automatically. However, there is gotcha with a lazy rating. What you need to do is also force i score before creating an anonymous function:

 funclist <- lapply(1:5, function(i) {force(i); function(x) print(i)}) funclist[[1]]('foo') [1] 1 funclist[[5]]('foo') [1] 5 
+5
source

My reading about what you want is to store the value inside the function environment when the function is defined, and then hold that value for internal calculations.

To do this, you need to close:

 i <- 3 test <- local({ i <- i function(x) x[i] }) test(letters[1:5]) # returns 'c' i <- 5 test(letters[1:5]) # still returns 'c' (ie i is local to the test closure) 

Is that what you wanted?

+2
source

All Articles