如何在R中有效地总结列表中的矩阵(无循环)?

问题描述:

假设我有一个函数返回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,但不起作用。

您可以使用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

通过内部嵌套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