在嵌套列表r中求和连续矩阵

时间:2016-03-27 17:40:12

标签: r

我有一个2x2矩阵的列表,看起来像这样:

matlist=
  list(structure(list(`1` = structure(c(8, 16, 3, 13), .Dim = c(2L, 2L)),
                    `2` = structure(c(6, 3, 0, 6), .Dim = c(2L, 2L)), 
                    `3` = structure(c(39,55, 15, 11), .Dim = c(2L, 2L)), 
                    `4` = structure(c(46, 53, 18,5), .Dim = c(2L, 2L)), 
                    `5` = structure(c(14, 6, 1, 12), .Dim = c(2L,2L)), 
                    `6` = structure(c(20, 6, 0, 12), .Dim = c(2L, 2L)), 
                    `7` = structure(c(4, 1, 0, 4), .Dim = c(2L, 2L))), 
                    .Names = c("1","2", "3", "4", "5", "6", "7" )), 
     structure(list(`1` = structure(c(38, 58, 0, 23), .Dim = c(2L, 2L)), 
                    `2` = structure(c(13, 10, 0, 7), .Dim = c(2L, 2L)), 
                    `3` = structure(c(22, 19, 1, 10), .Dim = c(2L,2L)), 
                    `4` = structure(c(8, 7, 0, 4), .Dim = c(2L, 2L)), 
                    `5` = structure(c(12,13, 3, 3), .Dim = c(2L, 2L)), 
                    `6` = structure(c(10, 8, 2, 2), .Dim = c(2L,2L)), 
                    `7` = structure(c(15, 14, 5, 5), .Dim = c(2L, 2L))), 
                    .Names = c("1", "2", "3", "4", "5", "6", "7"))
     )

这看起来像这样:

lapply(matlist, head,4)

[[1]]
[[1]]$`1`
     [,1] [,2]
[1,]    8    3
[2,]   16   13

[[1]]$`2`
     [,1] [,2]
[1,]    6    0
[2,]    3    6

[[1]]$`3`
     [,1] [,2]
[1,]   39   15
[2,]   55   11

[[1]]$`4`
     [,1] [,2]
[1,]   46   18
[2,]   53    5


[[2]]
[[2]]$`1`
     [,1] [,2]
[1,]   38    0
[2,]   58   23

[[2]]$`2`
     [,1] [,2]
[1,]   13    0
[2,]   10    7

[[2]]$`3`
     [,1] [,2]
[1,]   22    1
[2,]   19   10

[[2]]$`4`
     [,1] [,2]
[1,]    8    0
[2,]    7    4

我想要做的是对每个元素中的每两个连续矩阵求和。因此,我想总结第1和第2矩阵,第2和第3矩阵,第3和第4个maticres ......一直到最后两个矩阵'1'。我想对'2'中的所有矩阵执行相同操作....等等,对于较大列表中的所有嵌套列表。

我可以使用base总结列表中的所有矩阵:

lapply(matlist, function(x) Reduce('+', x))

或者我喜欢使用purrr(因为这将适合长链语法):

library(purrr)
matlist %>% map(~ Reduce('+', .))

[[1]]
     [,1] [,2]
[1,]  137   37
[2,]  140   63

[[2]]
     [,1] [,2]
[1,]  118   11
[2,]  129   54

如何在不使用循环的情况下为每个子列表中的每2个连续矩阵执行此操作 - 理想情况下,我有一个矢量化解决方案?

子列表1的前两个总和的所需输出示例:

 matlist[[1]][[1]]+matlist[[1]][[2]]
     [,1] [,2]
[1,]   14    3
[2,]   19   19

 matlist[[1]][[2]]+matlist[[1]][[3]]
     [,1] [,2]
[1,]   45   15
[2,]   58   17

2 个答案:

答案 0 :(得分:8)

这似乎有效:

{{1}}

答案 1 :(得分:4)

虽然我喜欢@ Frank的可读性解决方案,但我想添加另一种方法。如果将嵌套列表矩阵转换为数组列表,则可以对Mapmapply调用进行矢量化:

set.seed(123)
matlist <- replicate(100,
                     replicate(100, matrix(sample(4), nrow=2),
                               simplify=FALSE),
                     simplify=FALSE)

.array <- function(x) {
  a <- lapply(x, function(xx)array(unlist(xx), dim=c(2, 2, length(xx))))
  lapply(a, function(aa)aa[,,-dim(aa)[3]]+aa[,,-1])
}

frank <- function(x) {
  lapply(x, function(xx) Map(`+`, head(xx,-1), tail(xx,-1)))
}

library("rbenchmark")
benchmark(frank(matlist), .array(matlist), order = "relative",
          columns = c("test", "replications", "elapsed", "relative"))
#             test replications elapsed relative
#2 .array(matlist)          100   0.460    1.000
#1  frank(matlist)          100   2.386    5.187

也许值得将数据结构更改为数组而不是嵌套的矩阵列表。