可以lapply不能修改变量在更高范围
我经常要基本做到以下几点:可以lapply不能修改变量在更高范围
mat <- matrix(0,nrow=10,ncol=1)
lapply(1:10, function(i) { mat[i,] <- rnorm(1,mean=i)})
但是,我预计垫将有10张随机数的它,而是它有0(我并不担心这个标准部分,显然有一个正确的方法可以做到这一点,我担心会影响lapply的一个匿名函数中的mat)我能否不影响lapply中的矩阵mat?为什么不?是否有一个R的范围规则阻止了这个?
我在这个相关问题中讨论了这个问题:“Is R’s apply family more than syntactic sugar”。您会注意到,如果您查看for
和apply
的函数签名,它们有一个重要区别:for
循环评估表达式,而apply
循环评估函数。
如果您想改变应用功能范围之外的内容,则需要使用<<-
或assign
。或者更重要的是,使用类似for
的循环代替。但在处理函数之外的事情时,您确实需要小心,因为这可能会导致意外的行为。
在我看来,使用apply
函数的主要原因之一是明确的,因为它不会改变它之外的东西。这是函数式编程的核心概念,其中函数避免了side effects。这也是为什么apply
功能系列可以用于并行处理(以及类似功能存在于诸如雪的各种并行封装中)的原因。
最后,运行你的代码示例的正确方法是在参数也传递给你的函数像这样,和分配回输出:
mat <- matrix(0,nrow=10,ncol=1)
mat <- matrix(lapply(1:10, function(i, mat) { mat[i,] <- rnorm(1,mean=i)}, mat=mat))
它始终是最好要明确有关参数如果可能的话(因此mat=mat
)而不是推断它。
而不是实际改变垫,lapply只是返回垫的改变版本(作为列表)。您只需将其分配到垫子上并使用as.matrix()
将其重新转换为矩阵。
像lapply()
或sapply()
这样的高阶函数的主要优点之一就是你不必初始化你的“容器”(在这种情况下是矩阵)。
由于Fojtasek提示:
as.matrix(lapply(1:10,function(i) rnorm(1,mean=i)))
或者:
do.call(rbind,lapply(1:10,function(i) rnorm(1,mean=i)))
或者,仅仅作为一个数值向量:
sapply(1:10,function(i) rnorm(1,mean=i))
如果你真的想修改上面的变量你匿名函数的范围(在这个例子中是随机数发生器),使用<<-
> mat <- matrix(0,nrow=10,ncol=1)
> invisible(lapply(1:10, function(i) { mat[i,] <<- rnorm(1,mean=i)}))
> mat
[,1]
[1,] 1.6780866
[2,] 0.8591515
[3,] 2.2693493
[4,] 2.6093988
[5,] 6.6216346
[6,] 5.3469690
[7,] 7.3558518
[8,] 8.3354715
[9,] 9.5993111
[10,] 7.7545249
见this post约<<-
。但是,在这个特殊的例子,一个for循环只想让更多的意义:
mat <- matrix(0,nrow=10,ncol=1)
for(i in 1:10) mat[i,] <- rnorm(1,mean=i)
与创建一个索引变量,i
,在全球工作区的次要成本。