【问题标题】:Individual shift of each column in a matrix矩阵中每一列的单独移位
【发布时间】:2018-02-24 22:13:29
【问题描述】:

我寻找一个 R 代码来转换矩阵如下(a:原始矩阵,b:期望的输出),例如:

a <- matrix(c(1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6), nrow = 6, ncol = 4)    
b <- matrix(c(1,2,3,4,5,6,2,3,4,5,6,0,3,4,5,6,0,0,4,5,6,0,0,0), nrow = 6, ncol = 4)

a
     [,1] [,2] [,3] [,4]
[1,]    1    1    1    1
[2,]    2    2    2    2
[3,]    3    3    3    3
[4,]    4    4    4    4
[5,]    5    5    5    5
[6,]    6    6    6    6

b
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    2    3    4    5
[3,]    3    4    5    6
[4,]    4    5    6    0
[5,]    5    6    0    0
[6,]    6    0    0    0 

因此,第一列不移动,第二列上移一步,第三列上移两步,依此类推。移位的列用零填充。

以下链接对我没有帮助(也没有:双 for 循环、具有不同变量的函数、代码 diag 或 kronecker)。

R: Shift values in single column of dataframe UP

r matrix individual shift operations of elements

Rotate a Matrix in R

你有什么想法吗?谢谢。

【问题讨论】:

标签: r


【解决方案1】:

这似乎适用于data.table。应该在大型矩阵中表现良好:

library(data.table)

# One way
dt[, shift(.SD, 0:3, 0, "lead", FALSE), .SDcols = 1]

# Alternatively
dt[, shift(dt, 0:3, 0, "lead", FALSE)][, 1:4]

两者都返回:

   V1 V2 V3 V4
1:  1  2  3  4
2:  2  3  4  5
3:  3  4  5  6
4:  4  5  6  0
5:  5  6  0  0
6:  6  0  0  0

使用以下数据:

a <- matrix(c(1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6), nrow = 6, ncol = 4)

dt <- setDT(as.data.frame(a))

【讨论】:

  • 运行良好 - 太棒了!非常感谢。
  • 很好,很乐意为您提供帮助!
【解决方案2】:

我有一个使用 sapply 的原始解决方案。您在 sapply 的每次迭代中移动列,然后 sapply 连接所有输出,您可以将其提供给具有合适大小(初始矩阵大小)的矩阵

matrix(sapply(1:dim(a)[2], function(x){c(a[x:dim(a)[1], x], rep(0, (x - 1) ))}), ncol = dim(a)[2], nrow = dim(a)[1])

     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    2    3    4    5
[3,]    3    4    5    6
[4,]    4    5    6    0
[5,]    5    6    0    0
[6,]    6    0    0    0

【讨论】:

    【解决方案3】:

    您可以通过使用“a”中的值填充比“a”多一行的矩阵来移动列(在回收过程中会生成警告)。选择原始行数。用零替换右下三角。

    nr <- nrow(a)
    a2 <- matrix(a, ncol = ncol(a), nrow = nr + 1)[1:nr, ]
    
    a2[col(a2) + row(a2) > nr + 1] <- 0
    a2
    #      [,1] [,2] [,3] [,4]
    # [1,]    1    2    3    4
    # [2,]    2    3    4    5
    # [3,]    3    4    5    6
    # [4,]    4    5    6    0
    # [5,]    5    6    0    0
    # [6,]    6    0    0    0
    

    【讨论】:

      【解决方案4】:

      基于 tyluRp 的回答,这几乎对我有用,我建议遍历所有列并分别调用 shift。让我们从这里的随机数矩阵开始:

      a <- matrix(floor(10*runif(24)), ncol=4)
      
      a
           [,1] [,2] [,3] [,4]
      [1,]    8    4    8    3
      [2,]    0    6    9    0
      [3,]    1    6    0    7
      [4,]    0    3    9    7
      [5,]    2    4    2    9
      [6,]    4    8    5    6
      
      library(data.table)
      dt <- setDT(as.data.frame(a))
      

      现在是完成这项工作的循环......

      for (i in 2:length(dt)) dt[,i] <- shift(dt[,i,with=F],(i-1),0,"lead")
      

      ...通过将列替换为它们的移位版本。

      原始答案用移动的第一列的副本替换了所有列,从而丢失了数据。这可能是由于data.table 的群体行为所致。

      【讨论】:

        猜你喜欢
        • 2015-07-25
        • 1970-01-01
        • 1970-01-01
        • 2018-07-28
        • 1970-01-01
        • 2012-09-22
        • 1970-01-01
        • 2016-04-24
        • 2019-10-17
        相关资源
        最近更新 更多