On Jul 20, 2011, at 03:42 , Peter Lomas wrote: > Thanks very much to everyone who replied. Peter got me on my way with > the use diag() hint, and I came with a less pretty version of Dan's > first option almost at the same time as I got that email. Seems I > can't avoid one for loop, but one is better than two. >
What Peter? I see Dan and Dennis in the thread.... Anyway, last time the subject of diagonals came up, someone pointed out that recasting a matrix into a matrix with R+1 rows causes the 2nd column to move up on row, the 3rd column two rows, etc. So > m <-matrix(1:5,5,3) > m [,1] [,2] [,3] [1,] 1 1 1 [2,] 2 2 2 [3,] 3 3 3 [4,] 4 4 4 [5,] 5 5 5 > m2 <- matrix(,6,3) > suppressWarnings(m2[]<-m) # or: m2[seq_along(m)]<-m > m2[1:3,] [,1] [,2] [,3] [1,] 1 2 3 [2,] 2 3 4 [3,] 3 4 5 -Peter > Just as a note, with this code you have to make sure that you are in > fact giving it a matrix, or diag() will error. I fed it a data frame > unaware, but using as.matrix() works just fine. > > diagonals <- function(mat){ > R <- dim(mat)[1] > C <- dim(mat)[2] > output <- matrix(NA,(R-C+1),C) > for(i in 1:(R-C+1)) > output[i,] <- diag(mat[i:(i+C-1),]) > return(output) > } > example <- rbind(rep(1,3),rep(2,3),rep(3,3),rep(4,3),rep(5,3)) > diagonals(as.data.frame(example)) > > Error in output[i, ] <- diag(mat[i:(i + C - 1), ]) : > number of items to replace is not a multiple of replacement length > > Thanks again, > Peter > > > On Tue, Jul 19, 2011 at 17:34, Nordlund, Dan (DSHS/RDA) > <nord...@dshs.wa.gov> wrote: >>> -----Original Message----- >>> From: r-help-boun...@r-project.org [mailto:r-help-bounces@r- >>> project.org] On Behalf Of Peter Lomas >>> Sent: Tuesday, July 19, 2011 2:16 PM >>> To: r-help@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 >> >> ______________________________________________ >> R-help@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. >> >> > > ______________________________________________ > R-help@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. -- Peter Dalgaard Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Email: pd....@cbs.dk Priv: pda...@gmail.com ______________________________________________ R-help@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.