快速填充大R矩阵的方法

时间:2016-10-13 16:15:21

标签: r matrix

我正在尝试从较小的矩阵中填充一个大矩阵。

假设我有两个矩阵:

set.seed(1)
mat1 <- matrix(rnorm(100*20),nrow=100,ncol=20)
rownames(mat1) <- paste("R1",1:100,sep=".")
colnames(mat1) <- paste("F1",1:20,sep=".")

mat2 <- matrix(rnorm(200*10),nrow=200,ncol=10)
rownames(mat2) <- paste("R2",1:200,sep=".")
colnames(mat2) <- paste("F2",1:10,sep=".")

我需要创建的大矩阵将保留mat1mat2中所有行的组合,其列数将为ncol(mat1)+ncol(mat2)

combined.rownames <- expand.grid(rownames(mat1),rownames(mat2))

big.mat <- matrix(NA,nrow=nrow(mat1)*nrow(mat2),ncol=ncol(mat1)+ncol(mat2))
rownames(big.mat) <- paste(combined.rownames$Var1,combined.rownames$Var2,sep="_")

mat1将填充big.mat中与1:ncol(mat1)列对应的所有行:

idx1 <- match(combined.rownames$Var1,rownames(mat1))
big.mat[,1:ncol(mat1)] <- mat1[idx1,]

mat2将填充big.mat中与(ncol(mat1)+1):(ncol(mat1)+ncol(mat2))列对应的所有行:

idx2 <- match(combined.rownames$Var2,rownames(mat2))
big.mat[,(ncol(mat1)+1):(ncol(mat1)+ncol(mat2))] <- mat2[idx2,]

实际上我有一个矩阵列表:mat1mat2,...,matn,它们的尺寸高于此示例。

我的问题是,是否有更快/更有效的方式来填充big.mat

请注意,我的矩阵并不稀疏。

2 个答案:

答案 0 :(得分:1)

我认为使用行名作为索引效率很低。

ind <- expand.grid(1:nrow(mat1), 1:nrow(mat2))
big.mat2 <- cbind(mat1[ind[,1],], mat2[ind[,2],])

答案 1 :(得分:0)

如果问题使用了一些较小的矩阵并指定了“正确答案”,我是否理解这个问题可能会更清楚,但我认为这是重新发明“Kronecker产品”的努力。如果我是正确的,那么只用一个较小的例子就可以了;

mat1 <- matrix(1:20,nrow=4,ncol=5)
rownames(mat1) <- paste("R1",1:4,sep=".")
colnames(mat1) <- paste("F1",1:5,sep=".")
mat2 <- matrix(1:6,nrow=2,ncol=3)
rownames(mat2) <- paste("R2",1:2,sep=".")
colnames(mat2) <- paste("F2",1:3,sep=".")

 big <- kronecker(mat1, mat2)
 rownames(big) <- combined.rownames
 rownames(big) <- paste(combined.rownames$Var1, combined.rownames$Var2,sep="_")

 > big
          [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
R1.1_R2.1    1    3    5    5   15   25    9   27   45    13    39    65
R1.2_R2.1    2    4    6   10   20   30   18   36   54    26    52    78
R1.3_R2.1    2    6   10    6   18   30   10   30   50    14    42    70
R1.4_R2.1    4    8   12   12   24   36   20   40   60    28    56    84
R1.1_R2.2    3    9   15    7   21   35   11   33   55    15    45    75
R1.2_R2.2    6   12   18   14   28   42   22   44   66    30    60    90
R1.3_R2.2    4   12   20    8   24   40   12   36   60    16    48    80
R1.4_R2.2    8   16   24   16   32   48   24   48   72    32    64    96
          [,13] [,14] [,15]
R1.1_R2.1    17    51    85
R1.2_R2.1    34    68   102
R1.3_R2.1    18    54    90
R1.4_R2.1    36    72   108
R1.1_R2.2    19    57    95
R1.2_R2.2    38    76   114
R1.3_R2.2    20    60   100
R1.4_R2.2    40    80   120

仍然有一些疑问,这是否真的是答案,因为列数是产品而不是cols数的总和。请注意,kronecker使用*作为组合函数,但只要它是“矢量化”的,就可以使用其他函数。