When trying to create a list of similar functions using lapply
, I find that all the functions in the list are identical and equal to what the final element should be.
Consider the following:
pow <- function(x,y) x^y
pl <- lapply(1:3,function(y) function(x) pow(x,y))
pl
[[1]]
function (x)
pow(x, y)
<environment: 0x09ccd5f8>
[[2]]
function (x)
pow(x, y)
<environment: 0x09ccd6bc>
[[3]]
function (x)
pow(x, y)
<environment: 0x09ccd780>
When you try to evaluate these functions you get identical results:
pl[[1]](2)
[1] 8
pl[[2]](2)
[1] 8
pl[[3]](2)
[1] 8
What is going on here, and how can I get the result I desire (the correct functions in the list)?
The advantage of an anonymous function is that it does not have to be stored in a separate file. This can greatly simplify programs, as often calculations are very simple and the use of anonymous functions reduces the number of code files necessary for a program.
Anonymous functions are implemented using the Closure class. printf("Hello %s\r\n", $name); };
R passes promises, not the values themselves. The promise is forced when it is first evaluated, not when it is passed, and by that time the index has changed if one uses the code in the question. The code can be written as follows to force the promise at the time the outer anonymous function is called and to make it clear to the reader:
pl <- lapply(1:3, function(y) { force(y); function(x) pow(x,y) } )
This is no longer true as of R 3.2.0!
The corresponding line in the change log reads:
Higher order functions such as the apply functions and Reduce() now force arguments to the functions they apply in order to eliminate undesirable interactions between lazy evaluation and variable capture in closures.
And indeed:
pow <- function(x,y) x^y
pl <- lapply(1:3,function(y) function(x) pow(x,y))
pl[[1]](2)
# [1] 2
pl[[2]](2)
# [1] 4
pl[[3]](2)
# [1] 8
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With