[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