Home > Software engineering >  Make a matrix that outputs if an element of a vector is found in another vector in a fast way in R?
Make a matrix that outputs if an element of a vector is found in another vector in a fast way in R?

Time:10-16

Input

v1 <- c(5, 1, 4, 1, 1)
v2 <- c(1, 2, 4)

Desired Output

      1     2     4
5 FALSE FALSE FALSE
1  TRUE FALSE FALSE
4 FALSE FALSE  TRUE
1  TRUE FALSE FALSE
1  TRUE FALSE FALSE

I know I may use expand.grid and which but I can't figure this out.

Is using apply a fast way to do it?

EDIT : In fact I just need the sum of every column of the matrix (number of TRUE). How can I do this in an efficient way ?

CodePudding user response:

You can do this by using outer():

res <- outer(v1, v2, `==`)
rownames(res) <- v1
colnames(res) <- v2
res
##       1     2     4
## 5 FALSE FALSE FALSE
## 1  TRUE FALSE FALSE
## 4 FALSE FALSE  TRUE
## 1  TRUE FALSE FALSE
## 1  TRUE FALSE FALSE

If you're familiar with pipes, you can also do this without the multiple assignments:

library(magrittr)
outer(v1, v2, `==`) %>%
  set_rownames(v1) %>%
  set_colnames(v2)

CodePudding user response:

If you just want the sum of every column that is TRUE, you could do either of these:

v1 <- c(5, 1, 4, 1, 1)
v2 <- c(1, 2, 4)

`colnames<-`(t(matrix(Map(\(x) sum( v1 %in% x), v2))), v2)
#>      1 2 4
#> [1,] 3 0 1

`colnames<-`(t(matrix(colSums(outer(v1, v2, `==`)))), v2)
#>      1 2 4
#> [1,] 3 0 1

Not sure of the speed of either of these.

  • Related