Subscripting by a 2-column matrix M[cbind(v, seq_len(ncol(M)))] uses much less space (hence time) than making the ncol(M) by ncol(M) intermediate matrix just to extract its diagonal. E.g.
test <- function(n, seed) { if (!missing(seed)) set.seed(seed) M <- matrix(sample(LETTERS, 2*n, replace = TRUE), 2) v <- sample(2, n, replace=T) t1<-system.time(r1<-M[cbind(v,seq_len(ncol(M)))]) t2<-system.time(r2<-diag(M[v, 1:ncol(M)])) list(identical=identical(r1,r2), "time(matrix subscript)"=t1, "time(diag(big matrix))"=t2) } > test(100) $identical [1] TRUE $`time(matrix subscript)` user system elapsed 0.000 0.000 0.001 $`time(diag(big matrix))` user system elapsed 0.001 0.000 0.001 > test(1000) $identical [1] TRUE $`time(matrix subscript)` user system elapsed 0.000 0.000 0.001 $`time(diag(big matrix))` user system elapsed 0.082 0.021 0.103 > test(5000) $identical [1] TRUE $`time(matrix subscript)` user system elapsed 0.001 0.000 0.001 $`time(diag(big matrix))` user system elapsed 3.379 0.552 3.932 Bill Dunlap TIBCO Software Inc - Spotfire Division wdunlap tibco.com > -----Original Message----- > From: r-help-boun...@r-project.org > [mailto:r-help-boun...@r-project.org] On Behalf Of Marc Schwartz > Sent: Wednesday, June 10, 2009 4:42 PM > To: Logickle > Cc: rhelp help > Subject: Re: [R] How to extract from a matrix based on > indices in a vector? > > > On Jun 10, 2009, at 6:26 PM, Marc Schwartz wrote: > > > > > On Jun 10, 2009, at 12:36 PM, Logickle wrote: > > > >> > >> Sorry, there may be some lingo for describing the extraction > >> problem I have, > >> but I don't know it. > >> > >> I have a matrix of 2 rows and N columns, and a vector of N > 1s and 2s. > >> > >> Matrix M: > >> > >> 1 2 3 4 ... N > >> 1 A C D G ... > >> 2 B D F H ... > >> > >> Vector v: > >> > >> 1 2 2 1 2 1 1 ... N > >> > >> I'd like to apply v to M to get > >> > >> Vector w: > >> > >> A D F G ... > >> > >> I.e. each element of v is interpreted as a row-index used to > >> extract that > >> row's value from the corresponding column in M into the > >> corresponding column > >> of w. > >> > >> Also eventually nrow(M) > 2, in which case the value of the > >> elements of v > >> would range over 1:nrow(M). > >> > >> Seems it should be simple, but maybe not? > >> > >> Thanks! > >> > >> Doug > > > > Doug, > > > > Try this: > > > > # M is a character matrix > > > M > > 1 2 3 4 > > 1 "A" "C" "D" "G" > > 2 "B" "D" "F" "H" > > > > # v is a vector, equal in length to the number of columns in M > > > v > > [1] 1 2 2 1 > > > > # Get the diagonal of the matrix that results from the > combinations > > of indices > > > diag(M[v, 1:ncol(M)]) > > [1] "A" "D" "F" "G" > > > > > > I created a larger 2 row matrix to test further: > > > > set.seed(1) > > M <- matrix(sample(LETTERS, 40, replace = TRUE), 2, 20) > > > > > M > > [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] > > [1,] "G" "O" "F" "Y" "Q" "F" "R" "U" "S" "J" "Y" "Q" > > [2,] "J" "X" "X" "R" "B" "E" "J" "M" "Z" "U" "F" "D" > > [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20] > > [1,] "G" "A" "W" "M" "M" "V" "U" "S" > > [2,] "K" "J" "I" "P" "E" "R" "C" "K" > > > > > > and 'v': > > > > set.seed(2) > > v <- sample(2, 20, replace = TRUE) > > > > > v > > [1] 1 2 2 1 2 2 1 2 1 2 2 1 2 1 1 2 2 1 1 1 > > > > > > Then: > > > > > diag(M[v, 1:ncol(M)]) > > [1] "G" "X" "X" "Y" "B" "E" "R" "M" "S" "U" "F" "Q" "K" "A" > "W" "P" > > "E" > > [18] "V" "U" "S" > > > > > > Looks like it might work. > > > > Actually, the solution can be simplified further: > > # Using the second 'M': > > > diag(M[v, ]) > [1] "G" "X" "X" "Y" "B" "E" "R" "M" "S" "U" "F" "Q" "K" "A" > "W" "P" "E" > [18] "V" "U" "S" > > Marc > > ______________________________________________ > R-help@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@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.