I have been googeling and stackoverflowing this for a while but I cant seem to find the right answer.
I have a matrix that contains different characters strings like "a"
, or "gamma"
, or even numbers coerced to characters.
How do I get the array indices of matrix m
if an element of m
matches a value in a vector of candiate values (note that these values could be any character string). Here is what I tried. I though which(m %in% ...)
would do it but it doesnt return what I expected.
m <- matrix(c(0, "a", "gamma", 0, 0.5, 0, 0, 0, 0), ncol = 3)
m
#> [,1] [,2] [,3]
#> [1,] "0" "0" "0"
#> [2,] "a" "0.5" "0"
#> [3,] "gamma" "0" "0"
which(m == "a", arr.ind = TRUE) # as expected
#> row col
#> [1,] 2 1
which(m == "a" | m == "gamma", arr.ind = TRUE) # also obvious
#> row col
#> [1,] 2 1
#> [2,] 3 1
candidates <- c("a", "gamma", "b")
which(m %in% candidates, arr.ind = TRUE) # not what I expected
#> [1] 2 3
Created on 2019-09-11 by the reprex package (v0.3.0)
m
that match a value in candiates
. Any help?
The problem is that %in%
doesn't preserve the dimensions of the input. You can write your own function that would do that. For example
`%matin%` <- function(x, table) {
stopifnot(is.array(x))
r <- x %in% table
dim(r) <- dim(x)
r
}
candidates <- c("a", "gamma", "b")
which(m %matin% candidates, arr.ind = TRUE)
# row col
# [1,] 2 1
# [2,] 3 1
MrFlick's solution is probably one of the best you'll get but if you must stick with in-built functions in base R, here's one way -
which(matrix(m %in% candidates, dim(m)), arr.ind = T)
row col
[1,] 2 1
[2,] 3 1
Another way with lapply
and Reduce
but above should be faster -
which(Reduce("|", lapply(candidates, function(x) m == x)), arr.ind = T)
row col
[1,] 2 1
[2,] 3 1
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.