【问题标题】:How to shift each row of a matrix in R如何在R中移动矩阵的每一行
【发布时间】:2014-07-31 09:26:07
【问题描述】:

我有一个这种形式的矩阵:

a b c
d e 0
f 0 0

我想把它变成这样的东西:

a b c
0 d e
0 0 f

换档模式是这样的:

shift by 0 for row 1
shift by 1 for row 2
shift by 2 for row 3
...
shift by n-1 for row n

这当然可以通过 for 循环来完成。我想知道是否 有更好的方法吗?

【问题讨论】:

    标签: r data-manipulation


    【解决方案1】:

    假设您的示例具有代表性,即您始终具有由字母和零组成的三角形结构:

    mat <- structure(c("a", "d", "f", "b", "e", "0", "c", "0", "0"), 
                     .Dim = c(3L, 3L), .Dimnames = list(NULL, NULL))
    res <- matrix(0, nrow(mat), ncol(mat))
    res[lower.tri(res, diag=TRUE)] <- t(mat)[t(mat)!="0"]
    t(res)
    #     [,1] [,2] [,3]
    # [1,] "a"  "b"  "c" 
    # [2,] "0"  "d"  "e" 
    # [3,] "0"  "0"  "f" 
    

    【讨论】:

    • @CarlWitthoft 当然。但它避免了循环并且应该非常有效,所以我想我会分享这个选项。如果 OP 显示的数据不具有代表性,那不是我的错。
    • +1 如果满足假设,我认为这个解决方案非常聪明。
    • 为了避免假设,我们可以将mat的右下三角形设置为零?
    【解决方案2】:

    在我看来,headtail 解决方案的可读性不如 for 循环,甚至可能没有那么快。不过……

    t( sapply( 0:(nrow(mat)-1) , function(x) c( tail( mat[x+1,] , x ) , head( mat[x+1,] , nrow(mat)-x ) ) ) )
    #     [,1] [,2] [,3]
    #[1,] "a"  "b"  "c" 
    #[2,] "0"  "d"  "e" 
    #[3,] "0"  "0"  "f" 
    

    for 循环版本可能是...

    n <- nrow(mat)
    for( i in 1:n ){
        mat[i,] <- c( tail( mat[i,] , i-1 ) , head( mat[i,] , n-(i-1)  ) )
    }
    

    【讨论】:

      【解决方案3】:

      我想这就是你所需要的:

       mat<-matrix(1:25,5)
       mat
           [,1] [,2] [,3] [,4] [,5]
      [1,]    1    6   11   16   21
      [2,]    2    7   12   17   22
      [3,]    3    8   13   18   23
      [4,]    4    9   14   19   24
      [5,]    5   10   15   20   25
       for(j in 2:nrow(mat) ) mat[j,]<-mat[j, c(j:ncol(mat),1:(j-1))]
       mat
           [,1] [,2] [,3] [,4] [,5]
      [1,]    1    6   11   16   21
      [2,]    7   12   17   22    2
      [3,]   13   18   23    3    8
      [4,]   19   24    4    9   14
      [5,]   25    5   10   15   20
      

      【讨论】:

      • 你确定吗?这似乎不太适合我。
      • @SimonO'Hanlon 什么,我的测试代码?抱歉——我会回去解决这个问题。
      • 几乎!您似乎在左移,而 OP 在右移。
      • @SimonO'Hanlon 是的。但鉴于他选择的答案,显然他实际上想要的是推动“0”条目。所以我将把这个作为一个例子,供那些想做其他事情的人参考:-)
      猜你喜欢
      • 2020-12-04
      • 2019-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      • 1970-01-01
      相关资源
      最近更新 更多