[R] Taking all "complete" diagonals of a matrix

peter dalgaard pdalgd at gmail.com
Wed Jul 20 19:04:49 CEST 2011


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)
> <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
>>> 
>>> 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 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.
>> 
>> 
> 
> ______________________________________________
> 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.

-- 
Peter Dalgaard
Center for Statistics, Copenhagen Business School
Solbjerg Plads 3, 2000 Frederiksberg, Denmark
Phone: (+45)38153501
Email: pd.mes at cbs.dk  Priv: PDalgd at gmail.com



More information about the R-help mailing list