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 [[alternative HTML version deleted]]
Nordlund, Dan (DSHS/RDA)
2011-Jul-19 23:34 UTC
[R] Taking all "complete" diagonals of a matrix
> -----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) } Hope this is helpful, Dan Daniel J. Nordlund Washington State Department of Social and Health Services Planning, Performance, and Accountability Research and Data Analysis Division Olympia, WA 98504-5204
Hi: Does this work for you? mydiags <- function(mat) diag(mat[seq_len(ncol(mat)), ]) # Example: set.seed(103) u <- matrix(rpois(200, 10), ncol = 10) # > dim(u) # [1] 20 10 mydiags(u) # [1] 7 12 6 13 12 6 5 6 14 6 u[1:10, ] # as a double check HTH, Dennis On Tue, Jul 19, 2011 at 2:15 PM, Peter Lomas <peter.lomas at ucalgary.ca> wrote:> 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 > > ? ? ? ?[[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >