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 5 Comments
which(v, 'b'). Mind the order of the arguments.which(v, 'b') gives me an error message: >Error in which(v, 'b') : argument to 'which' is not logicalis.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 4 Comments
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'tis.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) or is.element(fruit, apple) could both be right depending on implementation of the is.element function.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
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 2 Comments
any(1==NA, na.rm=TRUE) returns 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))] 2 Comments
which is actually preferable sometimes for it gives you all the matching positions (as an array), unlike match. Although this was perhaps not what the OP asked for, unlike stackoverflow.com/questions/1169388/…which if you just want to find the elements not in Tset? You can just index pop directly; pop[!pop%in%Tset]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.
3 Comments
grep takes a regular expression as its first element, so to do an exact match for "b", either use^e$ or add , fixed=TRUE).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)
1 Comment
v %in% b
%-signs that is. The wordinis a reserved word in R use in for-loop construction.select(iris, contains("etal")).