当尝试使用lapply
创建类似函数的列表时,我发现列表中的所有函数都是相同的,并且等于最终元素应该是什么。
请考虑以下事项:
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>
当您尝试评估这些功能时,您会得到相同的结果:
pl[[1]](2)
[1] 8
pl[[2]](2)
[1] 8
pl[[3]](2)
[1] 8
这里发生了什么,我怎样才能得到我想要的结果(列表中的正确功能)?
答案 0 :(得分:20)
R传递promises,而不是值本身。承诺在第一次评估时被强制,而不是在它被传递时,并且到那时索引已经改变,如果使用问题中的代码。代码可以写成如下force在调用外部匿名函数时的承诺,并向读者说清楚:
pl <- lapply(1:3, function(y) { force(y); function(x) pow(x,y) } )
答案 1 :(得分:7)
从R 3.2.0开始,这已经不再适用了!
change log中的相应行显示:
高阶函数,例如apply函数和Reduce() 强制论证它们适用的函数以消除 惰性评估和变量捕获之间的不良交互 在关闭。
确实:
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