填充大 R 矩阵的快速方法

Posted

技术标签:

【中文标题】填充大 R 矩阵的快速方法【英文标题】:Fast way to populate a big R matrix 【发布时间】:2017-02-22 21:05:43 【问题描述】:

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

假设我有 2 个矩阵:

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

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

【问题讨论】:

【参考方案1】:

我认为使用行名作为索引是低效的。

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

【讨论】:

【参考方案2】:

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

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

对于这是否真的是答案仍有一些疑问,因为列数是乘积而不是列数的总和。请注意,kronecker 使用 * 作为组合函数,但可以使用另一个函数,只要它是“矢量化”的。

【讨论】:

以上是关于填充大 R 矩阵的快速方法的主要内容,如果未能解决你的问题,请参考以下文章

R语言创建使用矩阵(按行按列填充,矩阵命名,矩阵下标使用,数据框转换为矩阵)

R语言创建使用矩阵(按行按列填充,矩阵命名,矩阵下标使用,数据框转换为矩阵)

r语言如何生成矩阵偶数

将大矢量图像转换为二进制矩阵的快速方法

R 中的 hdf5 文件,用于通过 ID 进行快速随机访问

R:建立积分矩阵的最快方法?