[更新]我最初的分析是正确的,但得出的结论是错误的:)让我们在分析后得出结论。
下面是一些代码演示效果:
x <- lapply(1:3, function(x) sys.frame(sys.nframe()))
x[[1]] # An environment
x[[2]] # Another environment
x[[3]] # Yet nother environment
x[[1]]$x # 3!!! (should be 1)
x[[2]]$x # 3!! (should be 2)
x[[3]]$x # 3 as expected
# Accessing the variable within the function will "fix" the weird behavior:
x <- lapply(1:3, function(x) {x; sys.frame(sys.nframe())})
x[[1]]$x # 1
x[[2]]$x # 2
x[[3]]$x # 3
所以工作围绕在你的情况:
f <- function(a, b) { a;b; function(x) a*x + b }
顺便说一句,作为@詹姆斯指出存在force
功能,可访问变量更明确:
f <- function(a, b) { force(a);force(b); function(x) a*x + b }
Conclu sions
那么,@mbq和@hadley指出,这是由于懒惰的评价。它更容易与展示一个简单的for循环:
fs <- list(); for(i in 1:2) fs[[i]] <- f(a[[i]], b[[i]])
功能f
的x
参数将不得到价值a[[i]]
(这是0
),但整个表达和a
和i
存在的环境。当您访问x
时,会进行评估,因此在评估时使用i
。如果自从调用f
以来for循环已经开始,您将得到“错误”结果...
最初我说这是由于*apply
中的一个错误,事实并非如此。 ......但因为我恨是错的,我可以指出,*适用确实有在这些情况下的错误(或者更不一致的):
lapply(11:12, function(x) sys.call())
#[[1]]
#FUN(11:12[[1L]], ...)
#
#[[2]]
#FUN(11:12[[2L]], ...)
lapply(11:12, function(x) function() x)[[1]]() # 12
lapply(11:12, function(x) function() x)[[2]]() # 12
正如你看到的上面的lapply
代码说它调用与11:12[[1L]]
功能。如果您评估“稍后”应该仍然得到值11
- 但你实际上得到12
!
这是可能由于事实lapply
是用C语言实现的性能,而且欺骗了一下,所以它显示的表达是不是被评估的表达 - ERGO,一个bug ......
QED
+1找到这种奇怪的行为!我喜欢这些东西:-) – Tommy
可能不是一个适用的东西:'fs < - list();对于(我在1:2中)fs [[i]] < - f(a [[i]],b [[i]])'做同样的事情。 – pete