如何在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))
也可以使用transpose
,map
和reduce
从purrr包同时获得m1
和m2
$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
答
通过内部嵌套list
元素的名称(lapply(paste0("m", 1:2), ..
)我们循环,通过list
元素循环(lapply(d, ...
),提取与names
(d1[[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
但请注意,这些技术上仍然是循环,'Reduce'是一个隐藏(字节编译)for'循环。这不是我认为是矢量化的(但我仍然会使用替代1)。 – Roland
@Roland向量化函数也用于循环(在C中) –
当然,在C级别。性能差异在于R函数在每次迭代中是否被调用。 – Roland