2014-02-20 255 views
1

假设我有一个等维矩阵列表。例如:基于矩阵列表填充矩阵

mat = matrix(c(1,2,3,11,12,13,21,22,23), nrow = 3, ncol = 3) 
mat.list = rep(list(mat), 3) 
mat.list[[2]] = mat.list[[2]]*2.5 
mat.list[[3]] = mat.list[[3]]*3.5 

我要的是长度(mat.list)*的NcoI(垫)来填充尺寸长度(mat.list)* nrow(垫)超级矩阵 - 可能初始化如下:

super.mat = matrix(NA, nrow = length(mat.list)*nrow(mat), ncol = length(mat.list)*ncol(mat)) 

根据这样的规则: super.mat [N *(I-1)+ N,N *(J-1)+ N] = mat.list [[N] [I,J ]

其中:

N = length(mat.list) 

i和j表示矩阵N的行和列索引mat.list

我想在东西线:

populateMat = function(N, n, i, j, mat, super.mat){ 
super.mat[N*(i-1)+n,N*(j-1)+n] = mat[i,j] 
} 

一些联合应用功能在mat.list执行:

outer(1:nrow(mat), 1:ncol(mat), Vectorize(function(i,j) populateMat(N,1,i,j,mat,super.mat))) 

这里mat只是mat.list的单个元素,应该可以工作,但显然我需要一些帮助才能真正实现它的工作。

回答

1

一旦你意识到这只是一个块对角矩阵的重新安排,你可以想出一些像这样:

library(Matrix) 
N <- length(mat.list) 
bd <- do.call(bdiag, mat.list) 
i.idx <- order(rep(seq(nrow(bd)/N), N)) 
j.idx <- order(rep(seq(ncol(bd)/N), N)) 
bd[i.idx, j.idx] 
0

请问下列满足您的需求?:

sapply(seq_along(mat.list), 
     function(x) { 
     super.mat[(seq_len(nrow(super.mat))-1)%%nrow(mat.list[[x]])+1==x, 
        (seq_len(ncol(super.mat))-1)%%ncol(mat.list[[x]])+1==x] <<- mat.list[[x]] 
     return(NULL) 
     }) 

结果:

 [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] 
[1,] 1 NA NA 11 NA NA 21 NA NA 
[2,] NA 2.5 NA NA 27.5 NA NA 52.5 NA 
[3,] NA NA 3.5 NA NA 38.5 NA NA 73.5 
[4,] 2 NA NA 12 NA NA 22 NA NA 
[5,] NA 5.0 NA NA 30.0 NA NA 55.0 NA 
[6,] NA NA 7.0 NA NA 42.0 NA NA 77.0 
[7,] 3 NA NA 13 NA NA 23 NA NA 
[8,] NA 7.5 NA NA 32.5 NA NA 57.5 NA 
[9,] NA NA 10.5 NA NA 45.5 NA NA 80.5