如何重新排列矩阵?

时间:2019-12-15 14:04:59

标签: r sorting matrix

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

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

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

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

我知道如何“手动”执行此操作,但是我无法弄清楚这种重新排列所依据的规则。

2 个答案:

答案 0 :(得分:9)

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))

答案 1 :(得分:4)

这是基于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创建