Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selecting specific elements from a matrix all at once

Tags:

r

matrix

Is there a way I can select a bunch of prespecified elements all at once from a matrix? Specifically, suppose I have the following matrix:

      58        59        60       62        63        64
58  0.000000  3.772139  6.367721 8.978718 12.197210 13.401126
59  3.772139  0.000000  3.755554 5.935946  9.592700 11.664533
60  6.367721  3.755554  0.000000 5.999409  9.324764 11.991269
62  8.978718  5.935946  5.999409 0.000000  3.810169  6.762802
63 12.197210  9.592700  9.324764 3.810169  0.000000  3.796884
64 13.401126 11.664533 11.991269 6.762802  3.796884  0.000000

I want to select cells [1,2], [2,3], [3,4], [4,5], [5,6]. I realize that I can reference them by index, in this case I can run:

mymatrix[c(2,9,16,23,30)]

However, this is not very clear from reading the code later. Is there a way I can enter the actual (row, column) reference all at once?

like image 725
user1357015 Avatar asked Aug 16 '12 19:08

user1357015


3 Answers

A similar solution to that posted above, but one that deals with the situation of having a vector for the rows and a vector for the columns (which was my question when I came upon this thread) is as follows:

> rows <- c(1,2,3,4,5)
> cols <- c(2,3,4,5,6)
> call <- cbind(rows,cols)
> 
> mat[call]
[1] 3.772139 3.755554 5.999409 3.810169 3.796884
like image 151
ZombiePlan37 Avatar answered Oct 17 '22 07:10

ZombiePlan37


A solution to your specific situation would be to select the sub-matrix and use the diag function:

R> diag(x[-ncol(x),-1])
[1] 3.772139 3.755554 5.999409 3.810169 3.796884
like image 24
Joshua Ulrich Avatar answered Oct 17 '22 08:10

Joshua Ulrich


Indexing can be done with 2 column matrices. After converting those row and column numbers to a valid R object (rather than Matlab-style expressions):

> idxs <- gsub("\\]",")", gsub("\\[", "c(",  "[1,2], [2,3], [3,4], [4,5] ,[5,6]") )
# I edited the string value that idxs returned:
> midx <- rbind( c(1,2), c(2,3), c(3,4), c(4,5) ,c(5,6) )
> mat <-  matrix(scan(), nrow=6)  
1:  0.000000  3.772139  6.367721 8.978718 12.197210 13.401126
7:   3.772139  0.000000  3.755554 5.935946  9.592700 11.664533
13:   6.367721  3.755554  0.000000 5.999409  9.324764 11.991269
19:   8.978718  5.935946  5.999409 0.000000  3.810169  6.762802
25:  12.197210  9.592700  9.324764 3.810169  0.000000  3.796884
31:  13.401126 11.664533 11.991269 6.762802  3.796884  0.000000
37: 
Read 36 items
> mat[midx]
[1] 3.772139 3.755554 5.999409 3.810169 3.796884

If your goal were to index the super-diagonal that could be accomplished more generally:

> mat[col(mat)==row(mat)+1]
[1] 3.772139 3.755554 5.999409 3.810169 3.796884
like image 35
IRTFM Avatar answered Oct 17 '22 09:10

IRTFM