[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