user18894435
user18894435

Reputation: 531

which(arr.ind = TRUE) doesn't work with %in%

Take the following matrix for example, I want to find the array indices of some values.

set.seed(123)
mat <- matrix(sample(1:5, 15, TRUE), 5, 3)

#      [,1] [,2] [,3]
# [1,]    3    5    5
# [2,]    3    4    3
# [3,]    2    1    3
# [4,]    2    2    1
# [5,]    3    3    4

If it's a single value, say 2, then I can use which(..., arr.ind = TRUE) to find the coordinates.

which(mat == 2, arr.ind = TRUE)

#      row col
# [1,]   3   1
# [2,]   4   1
# [3,]   4   2

However, if I want to find the positions matched to a set of values, say c(1, 2), the code gives me a vector indices.

which(mat %in% 1:2, arr.ind = TRUE)

# [1]  3  4  8  9 14

How could I transform it to an 2-column form that indicate rows and columns from the matrix?

Upvotes: 3

Views: 671

Answers (1)

Darren Tsai
Darren Tsai

Reputation: 35594

The reason is that == keeps the structure of the matrix but %in% loses it.

mat == 2
#       [,1]  [,2]  [,3]
# [1,] FALSE FALSE FALSE
# [2,] FALSE FALSE FALSE
# [3,]  TRUE FALSE FALSE
# [4,]  TRUE  TRUE FALSE
# [5,] FALSE FALSE FALSE

mat %in% 2
# [1] FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE

You can use arrayInd() to convert a vector indices to the corresponding rows and columns in the matrix

arrayInd(which(mat %in% 1:2), dim(mat))

or turn mat %in% 1:2 back to a matrix to make which(arr.ind = TRUE) work.

which(array(mat %in% 1:2, dim(mat)), arr.ind = TRUE)

The both output

#      row col
# [1,]   3   1
# [2,]   4   1
# [3,]   3   2
# [4,]   4   2
# [5,]   4   3

Upvotes: 4

Related Questions