3

I'm looking for an efficient way to create a boolean vector which returns TRUE if one or more of a number of specified variables e.g. c(1,2,3) are in another vector e.g. c(4,5,6,1).

In this example the output sought would be TRUE as the element 1 is present in both vectors.

As far as I know %in% only permits checking one variable at a time and using the | operator is inefficient in this case given the number of potential variables I need to check for. Using intersect() returns logical(0) rather than FALSE, and sum(c(1,2,3) == c(4,5,6,1)) > 1 returns FALSE as the common elements are not in the same position.

Maël
  • 45,206
  • 3
  • 29
  • 67
ravinglooper
  • 169
  • 5

6 Answers6

5

You can use any:

vec <- c(1,2,3)
vec2 <- c(4,5,6,1)

any(vec %in% vec2)
#[1] TRUE
Maël
  • 45,206
  • 3
  • 29
  • 67
3

Using any is the most efficient way, but just to offer another solution, here's one using sum:

!!sum(c(1,2,3) %in% c(4,5,6,1))

 # [1] TRUE

Or we can use length:

length(base::intersect(c(1,2,3), c(4,5,6,1))) != 0
AndrewGB
  • 16,126
  • 5
  • 18
  • 49
M--
  • 25,431
  • 8
  • 61
  • 93
3

Here's another option using is.element with any:

vec1 <- c(1,2,3)
vec2 <- c(4,5,6,1)

any(is.element(vec1, vec2))

# [1] TRUE

Or another option is to use match with any (though would probably be less efficient):

any(match(vec1, vec2), na.rm = TRUE)
AndrewGB
  • 16,126
  • 5
  • 18
  • 49
3

One more not great option:

anyDuplicated( c(unique(vec), unique(vec2)) ) > 0
# [1] TRUE
s_baldur
  • 29,441
  • 4
  • 36
  • 69
3

Update: As commented by @M-- in case of no matches it gives back TRUE! Here is how to avoid this:

!all(!(v1 %in% v2))

First answer: One more with negating all:

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

!all(v1 %in% v2)
[1] TRUE
TarJae
  • 72,363
  • 6
  • 19
  • 66
2

Another option:

vector1 <- c(1,2,3)
vector2 <- c(4,5,6,1)

any(Reduce(intersect, list(vector1, vector2)))

Output:

[1] TRUE
Quinten
  • 35,235
  • 5
  • 20
  • 53