简体   繁体   中英

zigzag indexing in matrix

I have a matrix

mat <- matrix(rep(c("L","R"),5),ncol=2, byrow=TRUE)
cols <- c(1,1,2,1,1)
set.seed(42); test <- rnorm(5)

and I would like to get

First, one element from each row and the columns ins cols , yieldings here:

> res
#[1] "L" "L" "R" "L" "L"

Second, elements from selected rows, say those for which test>0 , and the corresponding columns in cols[test>0] , yielding here:

> res
#[1] "L" "R" "L" "L"

Is there some fast way of using cols to index mat ?

You can use matrix indexing :

mat[cbind(1:nrow(mat),cols)][test > 0]

From documentation of ?'[' :

When indexing arrays by [ a single argument i can be a matrix with as many columns as there are dimensions of x; the result is then a vector with elements corresponding to the sets of indices in each row of i.

Another way of using cols to index your matrix can be,

diag(mat[,cols])
#[1] "L" "L" "R" "L" "L"

#add the filter,
diag(mat[,cols])[test > 0]
#[1] "L" "R" "L" "L"

NOTE: As @digEmAll mentions, this will be terribly inefficient if the original matrix has a lot of rows. This is because it creates an nrow(mat) x nrow(mat) matrix in order to get the diagonal

mat <- matrix(rep(c("L","R"),5),ncol=2, byrow=TRUE)                  
cols <- c(1,1,2,1,1)                                                 
set.seed(42); (test <- rnorm(5))                                       
#> [1]  1.3709584 -0.5646982  0.3631284  0.6328626  0.4042683

Not sure why I get four elements > 0 when you got three. Anyway...

sapply(seq_along(1:nrow(mat)), function(i) mat[i, cols[i]])          
#> [1] "L" "L" "R" "L" "L"
sapply(seq_along(1:nrow(mat)), function(i) mat[i, cols[i]])[test > 0]
#> [1] "L" "R" "L" "L"

But matrix indexing is quite a bit faster and is the answer.

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