填充大 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=".")
我需要创建的大矩阵将包含mat1
和mat2
中所有行的组合,其列数将为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,]
实际上我有一个矩阵列表:mat1
、mat2
、...、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语言创建使用矩阵(按行按列填充,矩阵命名,矩阵下标使用,数据框转换为矩阵)