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


518

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


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

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

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


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

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

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))]

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.


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.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.