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.