列表中矩阵的滚动总和

时间:2018-11-06 16:03:31

标签: r list matrix sum

我有一个大小相等的矩阵列表:

a <- matrix(data = c(1,2,3,4,5,6,7,8,9), ncol = 3, nrow = 3)

b <- matrix(data = c(9,8,7,6,5,4,3,2,1), ncol = 3, nrow = 3)

c <- matrix(data = c(1,2,3,4,5,6,7,8,9), ncol = 3, nrow = 3)

d <- matrix(data = seq(from = 1, to = 9, by = 1), ncol = 3, nrow = 3)

e <- matrix(data = seq(from = 10, to = 90, by = 10), ncol = 3, nrow = 3)

f <- matrix(data = seq(from = 9, to = 1, by = -1), ncol = 3, nrow = 3)


test_list <- list(a, b, c, d, e, f)

如何对三个矩阵的每组求和,以使输出为两个矩阵,第一个是abcoutput_1)的总和第二个是defoutput_2)的总和?理想情况下,输出将是两个矩阵的新列表,例如

output_1 <- structure(c(11, 12, 13, 14, 15, 16, 17, 18, 19), .Dim = c(3L, 
3L)) 

output_2 <- structure(c(3L, 6L, 9L, 12L, 15L, 18L, 21L, 24L, 27L), .Dim = c(3L, 
3L))

5 个答案:

答案 0 :(得分:4)

library(purrr)
map(split(test_list, ceiling(seq_along(test_list)/3)), ~reduce(.x , `+`))

$`1`
     [,1] [,2] [,3]
[1,]   11   14   17
[2,]   12   15   18
[3,]   13   16   19

$`2`
     [,1] [,2] [,3]
[1,]    3   12   21
[2,]    6   15   24
[3,]    9   18   27

信贷to this answer获取整齐的拆分代码。

答案 1 :(得分:2)

43秒前,@ iod发表了与我相同的想法。我将其作为zack答案中的map-reduce-逻辑的基础表示出来:

lapply( split( test_list, cumsum( rep( c(T,F,F), 2))), function(x){ Reduce( "+", x)})
$`1`
     [,1] [,2] [,3]
[1,]   11   14   17
[2,]   12   15   18
[3,]   13   16   19

$`2`
     [,1] [,2] [,3]
[1,]    3   12   21
[2,]    6   15   24
[3,]    9   18   27

矿山使用了“ Reduce”,这在帮助页面上通过一组名为“功能编程语言中的通用高阶函数”的“ funprog”函数进行了描述。像iod一样,有时在Map和Reduce函数方面遇到一些困难。在这种情况下,需要使用Reduce而不是do.call,因为“ +”是二进制运算符,不能处理包含3个项目的向量。在内部,它与r.user.05apr的双循环答案没有太大区别。 lapply-split和Reduce都是真正的变相循环。

现在有几个不同的示例用于构造“ 3组”。我的方法是构造一个逻辑向量,然后运行cumsum来创建数字向量。 Masoud使用了glzack使用了ceiling(seq_along(test_list)/3),并礼貌地归功于它的灵感。

答案 2 :(得分:2)

只是带有data.table的涂鸦:

data.table::rbindlist(lapply(test_list, function(x) as.data.frame(x)))[, as.list(colSums(.SD)), 
                                     by = gl(ceiling(length(test_list)*nrow(test_list[[1]])/3), 
                                     3, length(test_list)*nrow(test_list[[1]]))]

答案 3 :(得分:1)

转换为数组,然后apply rowSums

test_array<-array(c(a,b,c,d,e,f),c(3,3,6))
apply(test_array[,1:3,1:3],2,rowSums)

     [,1] [,2] [,3]
[1,]   11   14   17
[2,]   12   15   18
[3,]   13   16   19

apply(test_array[,1:3,4:6],2,rowSums)

     [,1] [,2] [,3]
[1,]    3   12   21
[2,]    6   15   24
[3,]    9   18   27

答案 4 :(得分:1)

或者:

Matrix_Number <- 6

res <- vector("list", Matrix_Number / 3)
for (i in (1:(Matrix_Number/3))) {
  res[[i]] <- test_list[[(i-1)*3 + 1]] + test_list[[(i-1)*3 + 2]] + test_list[[(i-1)*3 + 3]]
}
res