我正在试图弄清楚如何获得矩阵的所有对角线。 例如,假设我有以下矩阵: A< - 矩阵(1:16,4)
使用diag(A)
函数将返回
[1] 1 6 11 16
除了主要的对角线,我想要一张上面和下面所有对角线的列表。
5 10 15
2 7 12
9 14
3 8
4
13
我找到了以下链接https://stackoverflow.com/a/13049722,它给我直接在主要对象上方和下方的对角线,但我似乎无法弄清楚如何扩展代码以获得任何大小矩阵的其余部分。我尝试了两个嵌套for循环,因为看起来某种矩阵下标的递增会产生我正在寻找的结果。我尝试在for循环中使用ncol(A),nrow(A),但似乎无法找出正确的组合。另外我知道在R中,for循环通常是不受欢迎的。
给出的代码是:
diag(A[-4,-1])
diag(A[-1,-4])
返回两个对角线,包括上部和下部
当然这是一个方阵,并不是我想要执行的所有矩阵都是方形的。如有必要,可以使用NA填充非正方形区域。我需要的答案可能是页面上的其他答案之一,但最初的问题涉及手段,总和等,这增加了一层复杂性,超出了我的目的。我觉得解决这个问题的方法非常简单,但它并没有发生在我身上。我也很惊讶我无法在任何地方找到这个问题,这似乎是一个很常见的问题。也许我不知道这个问题的正确术语。
答案 0 :(得分:54)
A <- matrix(1:16, 4)
# create an indicator for all diagonals in the matrix
d <- row(A) - col(A)
# use split to group on these values
split(A, d)
#
# $`-3`
# [1] 13
#
# $`-2`
# [1] 9 14
#
# $`-1`
# [1] 5 10 15
#
# $`0`
# [1] 1 6 11 16
#
# $`1`
# [1] 2 7 12
#
# $`2`
# [1] 3 8
#
# $`3`
# [1] 4
答案 1 :(得分:6)
由于您正在处理方形矩阵,因此将Gavin的答案转换为一个小函数应该非常容易,该函数首先计算应该用作偏移值的范围。这是一个功能:
AllDiags <- function(inmat, sorted = TRUE) {
Range <- ncol(inmat) - 1
Range <- -Range:Range
if (isTRUE(sorted)) Range <- Range[order(abs(Range))]
lapply(Range, function(x) {
inmat[row(inmat) == (col(inmat) - x)]
})
}
以下是样本矩阵的输出&#34; A&#34;。
AllDiags(A)
# [[1]]
# [1] 1 6 11 16
#
# [[2]]
# [1] 2 7 12
#
# [[3]]
# [1] 5 10 15
#
# [[4]]
# [1] 3 8
#
# [[5]]
# [1] 9 14
#
# [[6]]
# [1] 4
#
# [[7]]
# [1] 13
答案 2 :(得分:3)
这是一个基于观察的解决方案,您可以通过缩小和扩展矩阵来获得所有对角线。首先考虑行N col 1(得到diag)然后考虑行(N-1):和cols(1:2)。获得对角线。等。
N <- ncol(A)
rows <- cbind(c(N:1, rep(1,N-1)), c(rep(N,N), (N-1):1)) # row indeces
cols <- apply(rows, 2, rev) # col indeces
diagMatSubset <- function(mat, i1, i2, j1, j2) diag(mat[i1:i2, j1:j2, drop=FALSE])
Map(diagMatSubset, list(A), rows[,1], rows[,2], cols[,1], cols[,2])
[[1]]
[1] 4
[[2]]
[1] 3 8
[[3]]
[1] 2 7 12
[[4]]
[1] 1 6 11 16
[[5]]
[1] 5 10 15
[[6]]
[1] 9 14
[[7]]
[1] 13