J. Mini
J. Mini

Reputation: 1610

Why does lapply with closures give errors?

R inferno gives explaining the following output as a challenge:

>xr <- lapply(11:14,function(i) function() i^2)
>sapply(1:4, function(j) xr[[j]]())
[1]196 196 196 196

and I'm ashamed to say that I've failed it. What's going on? My guess is that it's something to do with i^2 remembering the environment that it was defined in, but I'm pretty sure that each element of xr used a different i, which also rules out thing being a lazy evaluation problem.

Upvotes: 1

Views: 86

Answers (1)

Sotos
Sotos

Reputation: 51592

Imagine that you create the following functions:

xr1 <- function() 11^ 2
xr2 <- function() 12 ^ 2
xr3 <- function() 13 ^ 2
xr4 <- function() 14 ^ 2

So when you call any one of them you get

xr1()
#[1] 121

xr3()
#[1] 169

Now instead of doing the same function 4 times for different numbers, we loop over the values we want to raise to power of 2 and create a list with 4 functions as its elements, i.e.

xr <- lapply(11:14, function(i) function() i ^ 2)

So now xr is a list with 4 functions.

Function 1 , i.e. xr[[1]]() will give 11^2 = 121

Function 2, i.e. xr[[2]]() will give 12^2 = 144 and so on...

So instead of calling each one separately, we now use sapply to loop over each element of xr and evaluate its function, hence

sapply(1:4, function(j) xr[[j]]())
#[1] 121 144 169 196

Upvotes: 3

Related Questions