【问题标题】:Fast way to populate a big R matrix填充大 R 矩阵的快速方法
【发布时间】: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

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

【问题讨论】:

    标签: r matrix


    【解决方案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 使用 * 作为组合函数,但可以使用另一个函数,只要它是“矢量化”的。

      【讨论】:

        猜你喜欢
        • 2018-01-23
        • 2021-07-19
        • 2018-05-05
        • 2016-06-25
        • 2021-10-26
        • 2013-12-25
        • 1970-01-01
        • 2018-05-11
        • 2020-09-27
        相关资源
        最近更新 更多