[R] Taking all "complete" diagonals of a matrix
Peter Lomas
peter.lomas at ucalgary.ca
Wed Jul 20 03:42:14 CEST 2011
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
>>
>> 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.
>
>
More information about the R-help
mailing list