【问题标题】:R duplicate a matrix several times and then bind by rows togetherR 多次复制一个矩阵,然后按行绑定在一起
【发布时间】:2013-11-04 14:42:47
【问题描述】:

我有以下矩阵

FI1  FI2 YI1 YI2 BAL1 BAL2 GRO1 GRO2  EQ1  EQ2
1 0.22 0.15 0.1 0.1 0.05 0.05 0.05 0.05 0.05 0.05
2 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00
3 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00
4 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00
5 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00
6 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00

现在我想让这个矩阵复制 10 次,然后放入一个矩阵中,使其看起来像这样(我在这里只显示 2 次)

FI1  FI2 YI1 YI2 BAL1 BAL2 GRO1 GRO2  EQ1  EQ2
1 0.22 0.15 0.1 0.1 0.05 0.05 0.05 0.05 0.05 0.05
2 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00
3 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00
4 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00
5 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00
6 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00
1 0.22 0.15 0.1 0.1 0.05 0.05 0.05 0.05 0.05 0.05
2 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00
3 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00
4 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00
5 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00
6 0.22 0.00 0.0 0.0 0.00 0.00 0.00 0.00 0.00 0.00

有人可以建议我一个简单的方法来完成这个吗? 谢谢 安德烈亚斯

【问题讨论】:

  • 通过研究提供的不同答案,您会学到很多东西,因为每个答案都说明了不同的技巧和权衡。

标签: r data-binding matrix rbind


【解决方案1】:
reprow <- function(x, m) {
    x[rep(seq_len(nrow(x)), times=m),,drop=FALSE]
}

a <- matrix(1:12, 3, 4)
b <- reprow(a, 3)

如果需要叉指方式,请改用x[rep(seq_len(nrow(x)), each=m),]

【讨论】:

    【解决方案2】:

    执行此操作的数学方法是将矩阵的Kronecker product 与一个向量相结合。

    mX = matrix(rnorm(100), 10, 10)
    mX %x% rep(1, numTimesToRepeat)
    

    【讨论】:

    • 这是一个聪明的解决方案,它将重复行,但以交叉的方式(即,您将得到重复的第 1 行 numTimesToRepeat,然后在第 2 行重复 numTimesToRepeat)。如果改为使用rep(1,numTimesToRepeat) %x% mX,您将得到@user2157086 所寻求的行为:在重复之前您将遍历所有行。
    【解决方案3】:

    如果您曾经使用过 matlab,repmat 函数非常有用,因为您所要做的就是指定矩阵以及您希望它在行和列方面复制多少次。这是一个 R 等价物:

    repmat = function(X,m,n){
    mx = dim(X)[1]
    nx = dim(X)[2]
    matrix(t(matrix(X,mx,nx*n)),mx*m,nx*n,byrow=T)} 
    
    m <- matrix(c(1:4), ncol = 2)
    repmat(m,2,3)
    >
         [,1] [,2] [,3] [,4] [,5] [,6]
    [1,]    1    3    1    3    1    3
    [2,]    2    4    2    4    2    4
    [3,]    1    3    1    3    1    3
    [4,]    2    4    2    4    2    4
    

    【讨论】:

      【解决方案4】:

      如果您的矩阵称为m,那么您可以只使用rep(),因为矩阵实际上只是一个原子向量,然后使用原始矩阵的列将其包裹在matrix() 中以获得正确的尺寸。你必须先 transpose 使用 t() 才能正确堆叠(感谢 @MatthewPlourde 指出这一点)。这个操作是完全向量化的,所以应该非常快速和高效。

      matrix( rep( t( m ) , 10 ) , ncol = ncol(m) , byrow = TRUE )
      

      示例

      m <- matrix( 1:9 , 3 )
      matrix( rep( t( m ) , 2 ) , ncol =  ncol(m) , byrow = TRUE )
      #     [,1] [,2] [,3]
      #[1,]    1    4    7
      #[2,]    2    5    8
      #[3,]    3    6    9
      #[4,]    1    4    7
      #[5,]    2    5    8
      #[6,]    3    6    9
      

      【讨论】:

      • OP 想要 m 堆叠。这会转置和堆叠。你可以改用matrix(rep(t(m), 2) , ncol=ncol(m) , byrow=TRUE)
      【解决方案5】:

      这是另一种方式:

      do.call(rbind, replicate(10, m, simplify=FALSE)) # where m is your matrix
      

      【讨论】:

      • 这是基于循环还是矢量化?
      • 如果你深入下去,一切都会循环;)。通常,您使用术语“向量化”来描述一个对原子向量进行一对一操作的函数。
      • replicate 只是sapply 调用的包装器,我称之为“高阶”矢量化。
      【解决方案6】:

      不优雅,但如果您只想继续工作,就足够简单了:

      m <- matrix(rnorm(60), ncol = 10)
      str(m)
      m2 <- rbind(m, m, m, m, m, m, m, m, m, m)
      str(m2)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-30
        • 1970-01-01
        • 2012-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多