从矩阵中获取所有对角向量
Get all diagonal vectors from matrix
我想弄清楚如何获得矩阵的所有对角线。
例如,假设我有以下矩阵:
A <- 矩阵(1:16,4)
使用 diag(A)
函数将 return
[1] 1 6 11 16
除了主对角线,我还想要一个包含其上方和下方所有对角线的列表。
5 10 15
2 7 12
9 14
3 8
4
13
我找到了下面的 link 它给出了主要对角线正上方和下方的对角线,但是我似乎无法弄清楚如何扩展代码以获得其余部分对于任何大小的矩阵。我尝试了两个嵌套的 for 循环,因为看起来矩阵下标的某种递增会产生我正在寻找的结果。我尝试在 for 循环中使用 ncol(A)、nrow(A),但似乎无法找出正确的组合。另外我知道 for 循环在 R 中通常不受欢迎。
给出的代码是:
diag(A[-4,-1])
diag(A[-1,-4])
其中 return 上下两条对角线
当然,这是一个方阵,并非我要对其执行此操作的所有矩阵都是方阵。如有必要,用 NA 填充非正方形区域是可以接受的。我需要的答案可能在页面上的其他答案之一中,但原始问题涉及手段、总和等,这增加了一层复杂性,超出了我想要做的事情。我觉得解决这个问题的方法会非常简单,但我并没有想到。我也很惊讶我无法在 SO 的任何地方找到这个问题,这似乎是一个足够普遍的问题。也许我不知道这个问题的正确术语。
由于您处理的是方阵,因此将 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)]
})
}
这是样本矩阵的输出 "A"。
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
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
这是一个基于观察的解决方案,您可以通过收缩和扩展矩阵来获得所有对角线。那是首先考虑行 N col 1(获取它的诊断),然后是行 (N-1): 和列 (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
我想弄清楚如何获得矩阵的所有对角线。 例如,假设我有以下矩阵: A <- 矩阵(1:16,4)
使用 diag(A)
函数将 return
[1] 1 6 11 16
除了主对角线,我还想要一个包含其上方和下方所有对角线的列表。
5 10 15
2 7 12
9 14
3 8
4
13
我找到了下面的 link 它给出了主要对角线正上方和下方的对角线,但是我似乎无法弄清楚如何扩展代码以获得其余部分对于任何大小的矩阵。我尝试了两个嵌套的 for 循环,因为看起来矩阵下标的某种递增会产生我正在寻找的结果。我尝试在 for 循环中使用 ncol(A)、nrow(A),但似乎无法找出正确的组合。另外我知道 for 循环在 R 中通常不受欢迎。
给出的代码是:
diag(A[-4,-1])
diag(A[-1,-4])
其中 return 上下两条对角线
当然,这是一个方阵,并非我要对其执行此操作的所有矩阵都是方阵。如有必要,用 NA 填充非正方形区域是可以接受的。我需要的答案可能在页面上的其他答案之一中,但原始问题涉及手段、总和等,这增加了一层复杂性,超出了我想要做的事情。我觉得解决这个问题的方法会非常简单,但我并没有想到。我也很惊讶我无法在 SO 的任何地方找到这个问题,这似乎是一个足够普遍的问题。也许我不知道这个问题的正确术语。
由于您处理的是方阵,因此将 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)]
})
}
这是样本矩阵的输出 "A"。
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
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
这是一个基于观察的解决方案,您可以通过收缩和扩展矩阵来获得所有对角线。那是首先考虑行 N col 1(获取它的诊断),然后是行 (N-1): 和列 (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