首页 > 解决方案 > 如何在R中绑定矩阵列表的所有行组合

问题描述

我有一个矩阵列表。该列表的长度未知(尽管在我的示例中我使用了 3 个 2x2 矩阵的列表)。

[[1]]
     [,1] [,2]
[1,]    1    1
[2,]    2    2

[[2]]
     [,1] [,2]
[1,]    3    3
[2,]    4    4

[[3]]
     [,1] [,2]
[1,]    5    5
[2,]    6    6

从这个列表中,我想生成列表中每个矩阵的行的所有可能组合的矩阵。即我想要这个作为输出:

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    1    3    3    5    5
[2,]    2    2    3    3    5    5
[3,]    1    1    4    4    5    5
[4,]    2    2    4    4    5    5
[5,]    1    1    3    3    6    6
[6,]    2    2    3    3    6    6
[7,]    1    1    4    4    6    6
[8,]    2    2    4    4    6    6

我看过其他示例(例如,我很想使用 expand.grid),但都倾向于扩展行元素的组合或应用一些我无法适应的其他功能。

此外 - 需要处理任何大小的矩阵列表。

我有一个解决方案,但我确信一定有一个更好/更短/更优雅/更快的隐藏在某个地方。你能帮我找到吗?

这是我的代码:

# New matrix will be stored in here.
# Don't like but is there a better way?
m.combs <- c()

expand.grid.2 <- function(lst) {

  if (is.null(m.combs)) {

    m.combs <<- lst

  } else {

    m.current <- m.combs
    n <- nrow(m.combs)

    for (i in 1:nrow(lst)) {

      if(i == 1)  # for first iteration cbind new matrix
        m.combs <<- cbind(m.combs, matrix(rep(lst[i, ], each = n), nrow = n))
      else        # for next iterations rbind new matrix
        m.combs <<- rbind(m.combs, cbind(m.current, matrix(rep(lst[i, ], each = n), nrow = n)))
    }
  }
}

m1 <- matrix(c(1,1,2,2), nrow = 2, ncol = 2, byrow = TRUE)
m2 <- matrix(c(3,3,4,4), nrow = 2, ncol = 2, byrow = TRUE)
m3 <- matrix(c(5,5,6,6), nrow = 2, ncol = 2, byrow = TRUE)
lst <- list(m1, m2, m3)

rapply(lst, expand.grid.2)
print(m.combs)

标签: rrecursioncombinationsapply

解决方案


这是一种可能的方法:

## get indices of all row combinations
m.combs <- expand.grid(lapply(l, function(x) seq_len(nrow(x))))

## extract rows and combine into matrix
do.call(cbind, Map(function(x, y) x[y, ], l, m.combs))
#>      [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,]    1    1    3    3    5    5
#> [2,]    2    2    3    3    5    5
#> [3,]    1    1    4    4    5    5
#> [4,]    2    2    4    4    5    5
#> [5,]    1    1    3    3    6    6
#> [6,]    2    2    3    3    6    6
#> [7,]    1    1    4    4    6    6
#> [8,]    2    2    4    4    6    6

首先用于expand.grid获取与我们希望生成的所有组合相对应的行索引(每个列表元素)。其次,提取相应的行并将它们组合成一个矩阵。

数据

mat <- matrix(rep(1:6, 2), ncol = 2)
l <- list(mat[1:2, ], mat[3:4, ], mat[5:6, ])

推荐阅读