[R] Taking all "complete" diagonals of a matrix
Nordlund, Dan (DSHS/RDA)
NordlDJ at dshs.wa.gov
Wed Jul 20 18:41:06 CEST 2011
> -----Original Message-----
> From: Peter Lomas [mailto:peter.lomas at ucalgary.ca]
> Sent: Tuesday, July 19, 2011 6:42 PM
> To: Nordlund, Dan (DSHS/RDA)
> Cc: r-help at 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)
> <NordlDJ at dshs.wa.gov> wrote:
> >> -----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
> >>
<<<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
More information about the R-help
mailing list