> -----Original Message----- > From: Peter Lomas [mailto:peter.lo...@ucalgary.ca] > Sent: Tuesday, July 19, 2011 6:42 PM > To: Nordlund, Dan (DSHS/RDA) > Cc: r-help@r-project.org > Subject: Re: [R] Taking all "complete" diagonals of a matrix > > 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. > > 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 > >>
<<<snip>>> > > 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, > > Peter, I am not sure what happened with the diagonals2 function that I posted yesterday (which I thought I had tested and it worked) because it clearly doesn't work. Here is a revised version that does work and is faster than using the diag() function. It will also work fine with a data frame as input. 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:C) output[,i] <- mat[i:(i+R-C),i] return(output) } Hope this is more 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.