我需要创建一个函数,该函数将根据矩阵中的值重新排列任何正方形矩阵。
所以,如果我有这样的矩阵:
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
因此,它是从最低(左上角)到最高(右下角)排序的,但是数字是按对角线排序的(是右词吗?),而不是行或列。
我知道如何“手动”执行此操作,但是我无法弄清楚这种重新排列所依据的规则。
答案 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
,该函数应该执行您要执行的操作。它使用split
和unsplit
并带有适当的因子。
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创建