Get all diagonal vectors from matrix

前端 未结 3 1832
我寻月下人不归
我寻月下人不归 2020-12-03 01:09

I\'m trying to figure out how to get all the diagonals of a matrix. For example, say I have the following matrix: A <- matrix(1:16,4)

using the diag(A)

相关标签:
3条回答
  • 2020-12-03 01:47

    Here is one solution based on an observation that you can get all the diagonals by shrinking and expanding the matrix. That is first consider row N col 1 (get diag of that) then rows (N-1): and cols (1:2). Get diagonal of that. etc..

    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
    
    0 讨论(0)
  • 2020-12-03 02:02

    Since you're dealing with square matrices, it should be really easy to convert Gavin's answer into a small function that first calculates the range that should be used as the offset values. Here's such a function:

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

    Here's the output on your sample matrix "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
    
    0 讨论(0)
  • 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
    
    0 讨论(0)
提交回复
热议问题