2016-09-15 26 views
0

假設我有一個函數返回2個矩陣。對於每個輸入i。如何在R中有效地總結列表中的矩陣(無循環)?

f<-function(i){ 
    m1=matrix(i,ncol=5,nrow=5) 
    m2=matrix(i*10,ncol=5,nrow=5) 
    r=list(m1=m1,m2=m2) 
    return(r) 
} 
d=lapply(1:3,f) 

我怎樣才能得到2件事情沒有for循環?

d[[1]]$m1+d[[2]]$m1+d[[3]]$m1 
d[[1]]$m2+d[[2]]$m2+d[[3]]$m2 

我試圖sum(lapply(1:3,function(x) (d[[x]]$m1)))爲M1,但不起作用。

回答

4

您可以使用Reduce

library(purrr) 
map(transpose(d), reduce, `+`) 

這將返回:

Reduce("+", lapply(d, function(x) x$m1)) 

也可以使用transposemapreducepurrr包同時獲得m1m2

$m1 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 6 6 6 6 6 
[2,] 6 6 6 6 6 
[3,] 6 6 6 6 6 
[4,] 6 6 6 6 6 
[5,] 6 6 6 6 6 

$m2 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 60 60 60 60 60 
[2,] 60 60 60 60 60 
[3,] 60 60 60 60 60 
[4,] 60 60 60 60 60 
[5,] 60 60 60 60 60 
+1

但請注意,這些技術上仍然是循環,'Reduce'是一個隱藏(字節編譯)for'循環。這不是我認爲是矢量化的(但我仍然會使用替代1)。 – Roland

+0

@Roland向量化函數也用於循環(在C中) –

+0

當然,在C級別。性能差異在於R函數在每次迭代中是否被調用。 – Roland

2

通過內部嵌套list元素的名稱(lapply(paste0("m", 1:2), ..)我們循環,通過list元素循環(lapply(d, ...),提取與namesd1[[nm]])相匹配的元素,並使用Reduce+(我沒看到對方的回答同時發佈)。

lapply(paste0("m", 1:2), function(nm) lapply(d, function(d1) Reduce(`+`, d1[[nm]]))) 
#[[1]] 
#  [,1] [,2] [,3] [,4] [,5] 
#[1,] 6 6 6 6 6 
#[2,] 6 6 6 6 6 
#[3,] 6 6 6 6 6 
#[4,] 6 6 6 6 6 
#[5,] 6 6 6 6 6 

#[[2]] 
#  [,1] [,2] [,3] [,4] [,5] 
#[1,] 60 60 60 60 60 
#[2,] 60 60 60 60 60 
#[3,] 60 60 60 60 60 
#[4,] 60 60 60 60 60 
#[5,] 60 60 60 60 60 
+1

謝謝!!,這一行是太恐怖了,我恐怕我無法弄清楚未來會有什麼意義..總是很難平衡可讀性和有效性。 – hxd1011