从小矩阵到大矩阵的所有可能矩阵

时间:2012-06-02 14:04:27

标签: r list

给定矩阵M和具有不同可能值的较小矩阵,我试图列出由于将这些小矩阵的组合叠加到矩阵M中而产生的所有可能矩阵。小矩阵将被插入具有相同矩阵M的M的位置中。行/列名称。

例如,请说:

 M <- matrix(rep(0, 49), nrow =7, ncol =7)
 rownames(M) <- colnames(M) <-seq(1,7)
 > M
 1 2 3 4 5 6 7
 1 0 0 0 0 0 0 0
 2 0 0 0 0 0 0 0
 3 0 0 0 0 0 0 0
 4 0 0 0 0 0 0 0
 5 0 0 0 0 0 0 0
 6 0 0 0 0 0 0 0
 7 0 0 0 0 0 0 0

# Generate first set of small matrices:
sub_mat_1_1 <- matrix(rep(1, 9), nrow =3, ncol =3)
rownames(sub_mat_1_1) <- colnames(sub_mat_1_1) <- c(2,3,5)
sub_mat_1_2 <- matrix(rep(2, 9), nrow =3, ncol =3)
rownames(sub_mat_1_2) <- colnames(sub_mat_1_2) <- c(2,3,5)
sub_mat_1_3 <- matrix(rep(3, 9), nrow =3, ncol =3)
rownames(sub_mat_1_3) <- colnames(sub_mat_1_3) <- c(2,3,5)
submatrix_1 <- list(sub_mat_1_1, sub_mat_1_2, sub_mat_1_3)

# Generate second set of small matrices:
submatrix_2 <- list()
sub_mat_2_1 <- matrix(rep(1, 4), nrow =2, ncol =2)
rownames(sub_mat_2_1) <- colnames(sub_mat_2_1) <- c(1,6)
sub_mat_2_2 <- matrix(rep(2, 4), nrow =2, ncol =2)
rownames(sub_mat_2_2) <- colnames(sub_mat_2_2) <- c(1,6)
submatrix_2 <- list(sub_mat_2_1, sub_mat_2_2)

# Generate list of small matrices:
submatrices <- list()
submatrices[[1]] <- submatrix_1
submatrices[[2]] <- submatrix_2

[[1]]
[[1]][[1]]
  2 3 5
2 1 1 1
3 1 1 1
5 1 1 1

[[1]][[2]]
  2 3 5
2 2 2 2
3 2 2 2
5 2 2 2

[[1]][[3]]
  2 3 5
2 3 3 3
3 3 3 3
5 3 3 3


[[2]]
[[2]][[1]]
  1 6
1 1 1
6 1 1

[[2]][[2]]
  1 6
1 2 2
6 2 2

由于第一个小矩阵集有3种可能性,第二个小矩阵集有2种,我试图在不使用for循环的情况下输出所有6个可能的矩阵作为列表:

[[1]]
  1 2 3 4 5 6 7
1 1 0 0 0 0 1 0
2 0 1 1 0 1 0 0
3 0 1 1 0 1 0 0
4 0 0 0 0 0 0 0
5 0 1 1 0 1 0 0
6 1 0 0 0 0 1 0
7 0 0 0 0 0 0 0

[[2]]
  1 2 3 4 5 6 7
1 1 0 0 0 0 1 0
2 0 2 2 0 2 0 0
3 0 2 2 0 2 0 0
4 0 0 0 0 0 0 0
5 0 2 2 0 2 0 0
6 1 0 0 0 0 1 0
7 0 0 0 0 0 0 0

[[3]]
  1 2 3 4 5 6 7
1 1 0 0 0 0 1 0
2 0 3 3 0 3 0 0
3 0 3 3 0 3 0 0
4 0 0 0 0 0 0 0
5 0 3 3 0 3 0 0
6 1 0 0 0 0 1 0
7 0 0 0 0 0 0 0

[[4]]
  1 2 3 4 5 6 7
1 2 0 0 0 0 2 0
2 0 1 1 0 1 0 0
3 0 1 1 0 1 0 0
4 0 0 0 0 0 0 0
5 0 1 1 0 1 0 0
6 2 0 0 0 0 2 0
7 0 0 0 0 0 0 0

[[5]]
  1 2 3 4 5 6 7
1 2 0 0 0 0 2 0
2 0 2 2 0 2 0 0
3 0 2 2 0 2 0 0
4 0 0 0 0 0 0 0
5 0 2 2 0 2 0 0
6 2 0 0 0 0 2 0
7 0 0 0 0 0 0 0

[[6]]
  1 2 3 4 5 6 7
1 2 0 0 0 0 2 0
2 0 3 3 0 3 0 0
3 0 3 3 0 3 0 0
4 0 0 0 0 0 0 0
5 0 3 3 0 3 0 0
6 2 0 0 0 0 2 0
7 0 0 0 0 0 0 0

一般来说,我可能会给出“小矩阵列表”,每个列都有自己的矩阵数。我将如何在此上下文中使用应用类型函数?

1 个答案:

答案 0 :(得分:1)

这提供了所要求的输出,但我必须同意评论者提出的问题不是很好。如何定义插入子矩阵值的位置?我只是假设您希望将它们插入到行和列的特定子集中,如请求的输出中所示...

将两个矩阵插入到M的指定行/列中的函数(全局定义,可能是不好的做法)

tmpmatf <- function(m1,m2,rc1=c(2,3,5),rc2=c(1,6)) {
    pos1 <- as.matrix(expand.grid(rc1,rc1))
    pos2 <- as.matrix(expand.grid(rc2,rc2))
    M[pos1] <- m1
    M[pos2] <- m2
    M
}

现在使用expand.grid创建一个数据框,其中包含来自每个子矩阵列表的索引的所有组合,并使用alply中的plyr(array-to-list)来运行{{ 1}}在每个组合上:

tmpmatf

这应该适用于你的两个子矩阵列表中的任意数量的子矩阵,但是如果你真的有更多(> 2)子矩阵列表,那么你没有给我们足够的信息来指定如何(例如)第三个子矩阵列表应该粘贴到更大的矩阵中......

请注意,第一部分(使用矩阵索引通过双列矩阵)比使用library(plyr) alply(expand.grid(seq(length(submatrices[[1]])), seq(length(submatrices[[2]]))), 1, function(x) { tmpmatf(submatrices[[1]][[x[[1]]]],submatrices[[2]][[x[[2]]]]) }) 循环将单个元素插入矩阵要快得多,但第二部分({{1实际上并不比一对迭代所有组合的嵌套for循环更快(任何?)更快 - 在这种情况下后者可能更清晰/更容易调试...