可以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”。您会注意到,如果您查看forapply的函数签名,它们有一个重要区别: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,在全球工作区的次要成本。