[R] Taking all "complete" diagonals of a matrix

Nordlund, Dan (DSHS/RDA) NordlDJ at dshs.wa.gov
Wed Jul 20 01:34:15 CEST 2011

```> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-
> project.org] On Behalf Of Peter Lomas
> Sent: Tuesday, July 19, 2011 2:16 PM
> To: r-help at r-project.org
> Subject: [R] Taking all "complete" diagonals of a matrix
>
> Hi R-Help!
>
> I am trying to find a nicer way of extracting all the "complete"
> diagonals
> of a matrix.  I am working with very large matrices that have many more
> rows
> than columns.  I want to be able to extract each of the diagonals that
> are
> as long as the number of columns in the matrix.  I have written a
> rather
> ugly function that presently does the job.  It illustrates what I am
> trying
> to do, but I feel like there must be a cleaner (and faster) way.  Does
> anybody have any ideas?  Here is what I've done so far:
>
> diagonals <- function(mat){
> output <- matrix(0,(dim(mat)[1]-dim(mat)[2]+1),NCOL(mat))
> for(i in 1:NROW(output)){
>    G <- c()
>    for(j in 1:NCOL(mat)){
>       G  <-  c(G,mat[(i+j-1),j])
>       }
>    output[i,]  <-  G
>   }
>  return(output)
> }
>
> example <- rbind(rep(1,3),rep(2,3),rep(3,3),rep(4,3),rep(5,3))
>
> example
>      [,1] [,2] [,3]
> [1,]    1    1    1
> [2,]    2    2    2
> [3,]    3    3    3
> [4,]    4    4    4
> [5,]    5    5    5
>
>  diagonals(example)
>      [,1] [,2] [,3]
> [1,]    1    2    3
> [2,]    2    3    4
> [3,]    3    4    5
>
> Many thanks,
> Peter
>

Peter,

Here are two possibilities.  I leave it up to you to determine whether they are cleaner or faster.

diagonals1 <- function(mat){
#setup
R <- dim(mat)[1]
C <- dim(mat)[2]
output <- matrix(0,(R-C+1),C)
#get diagonals
for(i in 1:(R-C+1)) output[i,] <- diag(mat[i:(i+C-1),])
return(output)
}

diagonals2 <- function(mat){
#setup
R <- dim(mat)[1]
C <- dim(mat)[2]
output <- matrix(0,(R-C+1),C)
#get diagonals
for(i in 1:(R-C+1)) output[,i] <- mat[i:(i+C-1),i]
return(output)
}