简体   繁体   中英

Select a column by column-name, but a different name for each row of a matrix in R?

suppose I have a matrix, I want to select values from column1 for the first row, column5 for the second row, and column4 for the third row (...). The columns are stored as column names in a vector and the position in this vector equals the row in which the column is to be chosen.

How can I achieve this efficiently, ie without looping?

(The background is: My purpose is to use this in a simulation, that's why I would love to vectorize it to speed it up)

A minimal example:

    # Creating my dummy matrix
    aMatrix <-matrix(1:15,3,5,dimnames=list(NULL,LETTERS[1:5]))
    aMatrix
         A B C  D  E
    [1,] 1 4 7 10 13
    [2,] 2 5 8 11 14
    [3,] 3 6 9 12 15

    # Here are the columns I want for each row
    columns <-c("A","E","D")
    columns
    [1] "A" "E" "D"
    # means: select for row 1 column "A" = 1,
    # select for row 2 column "E" = 11,
    # select for row 3 column "D" = 12

    # Now obviously I could do looping, but this is inefficient
    for (i in columns) print(grep(i,colnames(aMatrix))) #grep is necessary for my specific matrix-names in my simulation only.
    [1] 1 #wanting col. 1 for row 1
    [1] 5 #wanting col. 5 for row 2
    [1] 4 #wanting col. 4 for row 3

I just saw that looping the way I did it does not work very efficiently.

I was thinking about sapply/tapply but somehow could not get that to work, since there are two arguments that change (the row to be searched in the matrix, and the letter to be chosen from the target columnname-vector).

I would apprechiate your help a lot. Thanks!

Jana

PS I use "grep" here as the column names are substrings of the actual column names in the simulation I will run. But that substring-creation would have made the example more complicated, thus I skipped it.

As the help page ?`[` says, you can subset with a matrix to get individual elements. Each row of the subsetting matrix is an element, and the columns specify the indices for each dimension.

match(columns,colnames(aMatrix)) #gets the column indices
# [1] 1 5 4
b <- cbind(seq_along(columns),match(columns,colnames(aMatrix))) #subset matrix
#      [,1] [,2]
# [1,]    1    1 #first element: first row first column
# [2,]    2    5 #second element: second row fifth column
# [3,]    3    4 #third element: third row fourth column
aMatrix[b]
# [1]  1 14 12

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM