[R] How to extract from a matrix based on indices in a vector?

Marc Schwartz marc_schwartz at me.com
Thu Jun 11 01:41:36 CEST 2009


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




More information about the R-help mailing list