我經常要基本做到以下幾點:可以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的範圍規則阻止了這個?
我經常要基本做到以下幾點:可以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
,在全球工作區的次要成本。