【问题标题】:How to rearrange matrices?如何重新排列矩阵?
【发布时间】:2020-04-08 05:02:54
【问题描述】:

我需要创建一个函数,它将根据矩阵中的值重新排列任何方阵。

所以如果我有这样的矩阵:

M <- matrix(1:16, ncol = 4)
M
#>      [,1] [,2] [,3] [,4]
#> [1,]    1    5    9   13
#> [2,]    2    6   10   14
#> [3,]    3    7   11   15
#> [4,]    4    8   12   16

重新排列后它需要看起来像这样:

      [,1] [,2] [,3] [,4]
[1,]    1    3    6   10
[2,]    2    5    9   13
[3,]    4    8   12   15
[4,]    7   11   14   16

所以它是从最低(左上角)到最高(右下角)排序的,但是数字是按对角线排序的(是正确的词吗?)而不是按行或列。

我知道如何“手动”执行此操作,但我无法弄清楚此重新排列所遵循的任何规则。

【问题讨论】:

    标签: r sorting matrix


    【解决方案1】:

    1) row(m) + col(m) 在反向对角线上是恒定的,所以:

    M <- replace(m, order(row(m) + col(m)), m)
    

    赠予:

    > M
         [,1] [,2] [,3] [,4]
    [1,]    1    3    6   10
    [2,]    2    5    9   13
    [3,]    4    8   12   15
    [4,]    7   11   14   16
    

    不清楚在对角线上排序是否意味着它们只是从存储顺序中解开到反向对角线上,或者它们实际上是在每个反向对角线内排序之后。在问题的示例中,两种解释给出了相同的答案;但是,如果您确实希望之后使用不同的数据在反向对角线内对结果进行排序,那么应用这个:

    ave(M, row(M) + col(M), FUN = sort)
    

    2) 更长的版本:

    M2 <- matrix(m[order(unlist(tapply(seq_along(m), row(m) + col(m), c)))], nrow(m))
    

    【讨论】:

    • 感谢您的回答,但我无法理解您代码的内部工作原理。例如如何添加排序元素,使数字始终沿对角线从小到大按升序排序。谢谢
    • 已经简化了。
    • 关于排序,已经扩展了答案。
    • 非常感谢,您非常有帮助!
    【解决方案2】:

    这是基础 R 中的一个函数columns_to_diagonals,它应该可以满足您的需求。它使用 splitunsplit 和适当的因子。

    columns_to_diagonals <- function(M) {
      n <- ncol(M)
      f <- matrix(rep(1:(2*n-1), c(1:n, (n-1):1)), ncol = n)
      m <- split(M, f)
      d <- row(M) + col(M)
      matrix(unsplit(m, d), ncol = n)
    }
    

    首先,我们可能会在您的原始案例上进行测试:

    M <- matrix(1:16, ncol = 4)
    columns_to_diagonals(M)
    #>      [,1] [,2] [,3] [,4]
    #> [1,]    1    3    6   10
    #> [2,]    2    5    9   13
    #> [3,]    4    8   12   15
    #> [4,]    7   11   14   16
    

    然后是一个更大的随机置换矩阵,以检查它是否也正常:

    M <- matrix(sample(1:25), ncol = 5)
    M
    #>      [,1] [,2] [,3] [,4] [,5]
    #> [1,]    4   15   12   10   21
    #> [2,]   19    7    5   23    6
    #> [3,]    9   17    2    8    1
    #> [4,]    3   11   16   25   14
    #> [5,]   22   18   20   13   24
    columns_to_diagonals(M)
    #>      [,1] [,2] [,3] [,4] [,5]
    #> [1,]    4    9   15   18   20
    #> [2,]   19   22   11   16   25
    #> [3,]    3   17    2    8    6
    #> [4,]    7    5   23   21   14
    #> [5,]   12   10   13    1   24
    

    reprex package (v0.2.1) 于 2019 年 12 月 15 日创建

    【讨论】:

    • 您好,非常感谢您的快速响应!我想我能够理解你的方法:D。我坐在这里,思考如何更改每个单独的数字:D。我对代码进行了轻微更改,使其从最低到最高排序:`s
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-23
    • 1970-01-01
    • 1970-01-01
    • 2012-06-11
    相关资源
    最近更新 更多