Tester si un vecteur contient un élément donné

518

Comment vérifier si un vecteur contient une valeur donnée?

medriscoll
la source
38
parfois je me demande pourquoi R n'utilise pas le mot contient pour rendre les utilisateurs plus faciles
greg121
12
considérer que "in" est contenu dans "conta (in) s"; Je dirais que "in" est un concurrent considérablement concis dans ce contexte
hedgedandlevered
1
Peut-être avec l'ajout de %signes flanquants . Le mot inest un mot réservé dans R utilisé dans la construction de boucles for.
IRTFM
@ greg121 dplyr a déjà une fonction contient , mais elle est utilisée dans un autre but: sélectionner une colonne dans un bloc de données. Par exemple select(iris, contains("etal")).
Paul Rougieux
Existe-t-il un moyen concis de le faire pour des nombres réels avec une précision donnée?
mlt

Réponses:

500

Les fonctions match()(retourne la première apparition) et %in%(retourne un booléen) sont conçues pour cela.

v <- c('a','b','c','e')

'b' %in% v
## returns TRUE

match('b',v)
## returns the first location of 'b', in this case: 2
medriscoll
la source
qu'en est-il d'obtenir toutes les apparences, pas seulement la première?
StatsSorceress
Je viens peut-être un peu tard. which(v, 'b'). Attention à l'ordre des arguments.
Niklas Mertsch
Votre which(v, 'b')me donne un message d'erreur:> Erreur dans laquelle (v, 'b'): argument à 'qui' n'est pas logique
Capt.Krusty
176

is.element() rend le code plus lisible et est identique à %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
Justin Nafe
la source
6
Je sais que la documentation dit is.element(x, y) is identical to x %in% y. Mais, je ne sais pas pourquoi, is.elementsfonctionne lors du mélange d'entiers et de chiffres et %in%ne fonctionne pas
pomber
@pomber: Pouvez-vous en donner un exemple?
discipulus
@pomber est-il réparé?
vasili111
2
La lisibilité supérieure is.element()vs %in%est subjective. On peut faire valoir qu'un opérateur infixe est plus lisible car il élimine l'ambiguïté dans l'ordre des arguments. apple in fruitest logique, fruit in applenon. is.element(apple, fruit)ou is.element(fruit, apple)pourraient tous deux avoir raison selon la mise en œuvre de la is.elementfonction.
rileymcdowell
70

Je vais regrouper les options en fonction de la sortie. Supposons le vecteur suivant pour tous les exemples.

v <- c('z', 'a','b','a','e')

Pour vérifier la présence:

%dans%

> 'a' %in% v
[1] TRUE

tout()

> any('a'==v)
[1] TRUE

is.element ()

> is.element('a', v)
[1] TRUE

Pour trouver la première occurrence:

rencontre()

> match('a', v)
[1] 2

Pour trouver toutes les occurrences comme vecteur d'indices:

lequel()

> which('a' == v)
[1] 2 4

Pour trouver toutes les occurrences comme vecteur logique :

==

> 'a' == v
[1] FALSE  TRUE FALSE  TRUE FALSE

Edit: Suppression de grep () et grepl () de la liste pour la raison mentionnée dans les commentaires

ishandutta2007
la source
6
Comme déjà commenté ici et ici , n'utilisez pas d' grep()expressions régulières pour trouver des correspondances exactes.
Uwe
69

La fonction any () rend le code lisible

> 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
Dan Goldstein
la source
9
Sachez que cela se comporte différemment de %in%: any(1==NA)retours NA, où 1 %in% NAretours FALSE.
@ user3603486: any(1==NA, na.rm=TRUE)renvoie FALSE.
AkselA
36

Vous pouvez utiliser l' %in%opérateur:

vec <- c(1, 2, 3, 4, 5)
1 %in% vec # true
10 %in% vec # false
ars
la source
19

Aussi pour trouver la position de l'élément "qui" peut être utilisé comme

pop <- c(3,4,5,7,13)

which(pop==13)

et pour trouver les éléments qui ne sont pas contenus dans le vecteur cible, on peut faire ceci:

pop <- c(1,2,4,6,10)

Tset <- c(2,10,7)   # Target set

pop[which(!(pop%in%Tset))]
Armin
la source
whichest en fait parfois préférable car il vous donne toutes les positions correspondantes (sous forme de tableau), contrairement à match. Bien que ce ne soit peut-être pas ce que l'OP demandait, contrairement à stackoverflow.com/questions/1169388/…
Fizz
2
Pourquoi vous embêter whichsi vous voulez juste trouver les éléments qui ne s'y trouvent pas Tset? Vous pouvez simplement indexer popdirectement; pop[!pop%in%Tset]
Houshalter
13

J'aime vraiment grep () et grepl () à cet effet.

grep () renvoie un vecteur d'entiers, qui indiquent où se trouvent les correspondances.

yo <- c("a", "a", "b", "b", "c", "c")

grep("b", yo)
[1] 3 4

grepl () renvoie un vecteur logique, avec "TRUE" à l'emplacement des correspondances.

yo <- c("a", "a", "b", "b", "c", "c")

grepl("b", yo)
[1] FALSE FALSE  TRUE  TRUE FALSE FALSE

Ces fonctions sont sensibles à la casse.

ojdajuiceman
la source
10
Par défaut, grepprend une expression régulière comme premier élément, donc pour faire une correspondance exacte pour "b", utilisez ^e$ou ajoutez , fixed=TRUE).
reinierpost
10
N'utilisez pas l'expression régulière pour les correspondances exactes. Ceci est dangereux et peut avoir des résultats inattendus
David Arenburg
9
Oui, c'est une idée terrible, pas bonne, très mauvaise - inefficace et garantie de casser. Par exemple myvar <- 'blah'; grepl('b', myvar, fixed=TRUE), reviendra TRUEmême si «b» n'est pas dedans myvar.