How to check if a vector contains a given value?
8 Answers
Both the match()
(returns the first appearance) and %in%
(returns a Boolean) functions are designed for this.
v <- c('a','b','c','e')
'b' %in% v
## returns TRUE
match('b',v)
## returns the first location of 'b', in this case: 2
-
what about getting all appearances, not just the first one? Commented Mar 15, 2018 at 0:54
-
1Maybe I come a little late.
which(v, 'b')
. Mind the order of the arguments. Commented Dec 19, 2018 at 19:40 -
Your
which(v, 'b')
gives me an error message: >Error in which(v, 'b') : argument to 'which' is not logical Commented Aug 17, 2019 at 10:08 -
1The syntax is which(v == b) or any other logical operator. In this case, the return from this would be 2. If v were c("b", "b", "c", "b", "d"), the return to which(v == b) would be 1, 2, 4.– khtadCommented Jun 26, 2020 at 21:33
is.element()
makes for more readable code, and is identical to %in%
v <- c('a','b','c','e')
is.element('b', v)
'b' %in% v
## both return TRUE
is.element('f', v)
'f' %in% v
## both return FALSE
subv <- c('a', 'f')
subv %in% v
## returns a vector TRUE FALSE
is.element(subv, v)
## returns a vector TRUE FALSE
-
8I know the documentation says
is.element(x, y) is identical to x %in% y
. But, I dont know why,is.elements
works when mixing integers and numerics and%in%
doesn't– pomberCommented Dec 28, 2014 at 6:21 -
-
-
9The superior readability
is.element()
vs%in%
is subjective. A case can be made that an infix operator is more readable because it eliminates ambiguity in the order of arguments.apple in fruit
makes sense,fruit in apple
does not.is.element(apple, fruit)
oris.element(fruit, apple)
could both be right depending on implementation of theis.element
function. Commented Jan 3, 2020 at 16:36
I will group the options based on output. Assume the following vector for all the examples.
v <- c('z', 'a','b','a','e')
For checking presence:
%in%
> 'a' %in% v
[1] TRUE
any()
> any('a'==v)
[1] TRUE
is.element()
> is.element('a', v)
[1] TRUE
For finding first occurance:
match()
> match('a', v)
[1] 2
For finding all occurances as vector of indices:
which()
> which('a' == v)
[1] 2 4
For finding all occurances as logical vector:
==
> 'a' == v
[1] FALSE TRUE FALSE TRUE FALSE
Edit: Removing grep() and grepl() from the list for reason mentioned in comments
-
8
The any() function makes for readable code
> w <- c(1,2,3)
> any(w==1)
[1] TRUE
> v <- c('a','b','c')
> any(v=='b')
[1] TRUE
> any(v=='f')
[1] FALSE
-
11Be aware this behaves differently from
%in%
:any(1==NA)
returnsNA
, where1 %in% NA
returnsFALSE
.– user3603486Commented Mar 23, 2017 at 1:34 -
You can use the %in%
operator:
vec <- c(1, 2, 3, 4, 5)
1 %in% vec # true
10 %in% vec # false
Also to find the position of the element "which" can be used as
pop <- c(3, 4, 5, 7, 13)
which(pop==13)
and to find the elements which are not contained in the target vector, one may do this:
pop <- c(1, 2, 4, 6, 10)
Tset <- c(2, 10, 7) # Target set
pop[which(!(pop%in%Tset))]
-
which
is actually preferable sometimes for it gives you all the matching positions (as an array), unlikematch
. Although this was perhaps not what the OP asked for, unlike stackoverflow.com/questions/1169388/… Commented Feb 7, 2015 at 16:27 -
2Why bother with
which
if you just want to find the elements not inTset
? You can just indexpop
directly;pop[!pop%in%Tset]
Commented Feb 20, 2017 at 23:11
I really like grep() and grepl() for this purpose.
grep() returns a vector of integers, which indicate where matches are.
yo <- c("a", "a", "b", "b", "c", "c")
grep("b", yo)
[1] 3 4
grepl() returns a logical vector, with "TRUE" at the location of matches.
yo <- c("a", "a", "b", "b", "c", "c")
grepl("b", yo)
[1] FALSE FALSE TRUE TRUE FALSE FALSE
These functions are case-sensitive.
-
12By default,
grep
takes a regular expression as its first element, so to do an exact match for"b"
, either use^e$
or add, fixed=TRUE
). Commented Jan 7, 2016 at 7:45 -
12Do not use regex for exact matches. This is dangerous and can have unexpected results Commented Sep 10, 2016 at 17:54
-
10Yeah, this is a terrible, no good, very bad idea - inefficient and guaranteed to break. E.g.
myvar <- 'blah'; grepl('b', myvar, fixed=TRUE)
will returnTRUE
even though 'b' is not inmyvar
.– user3603486Commented Mar 23, 2017 at 1:31
Another option to check if a element exists in a vector is by using the %in{}%
syntax from the inops
package like this:
library(inops)
#>
#> Attaching package: 'inops'
#> The following object is masked from 'package:base':
#>
#> <<-
v <- c('a','b','c','e')
v %in{}% c("b")
#> [1] FALSE TRUE FALSE FALSE
Created on 2022-07-16 by the reprex package (v2.0.1)
%
-signs that is. The wordin
is a reserved word in R use in for-loop construction.select(iris, contains("etal"))
.