Probar si un vector contiene un elemento dado

518

¿Cómo verificar si un vector contiene un valor dado?

medriscoll
fuente
38
a veces me pregunto por qué R simplemente no usa la palabra contiene para facilitar a los usuarios
greg121
12
considere que "in" está contenido en "conta (in) s"; Yo diría que "en" es un contendiente considerablemente conciso en este contexto
cubrió el
1
Quizás con la adición de %signos de flanqueo que es. La palabra ines una palabra reservada en el uso de R en la construcción de bucles for.
IRTFM
@ greg121 dplyr ya tiene una función contiene , pero se usa para un propósito diferente: seleccionar una columna en un marco de datos. Por ejemplo select(iris, contains("etal")).
Paul Rougieux
¿Hay una manera concisa de hacerlo para números reales con una precisión dada?
mlt

Respuestas:

500

Tanto las funciones match()(devuelve la primera aparición) como %in%(devuelve un booleano) están diseñadas para esto.

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
fuente
¿Qué hay de obtener todas las apariencias, no solo la primera?
EstadísticasSorceress
Tal vez llego un poco tarde. which(v, 'b'). Cuidado con el orden de los argumentos.
Niklas Mertsch
Tu which(v, 'b')mensaje me da un error:> Error en el cual (v, 'b'): argumento para 'cuál' no es lógico
Capt.Krusty
176

is.element() crea un código más legible y es idéntico a %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
fuente
66
Sé que la documentación dice is.element(x, y) is identical to x %in% y. Pero, no sé por qué, is.elementsfunciona al mezclar números enteros y numéricos y %in%no lo hace
pomber
@ pomber: ¿Podría dar un ejemplo de esto?
discipulus
@pomber, ¿está arreglado?
vasili111
2
La legibilidad superior is.element()vs %in%es subjetiva. Se puede argumentar que un operador infijo es más legible porque elimina la ambigüedad en el orden de los argumentos. apple in fruittiene sentido, fruit in appleno. is.element(apple, fruit)o is.element(fruit, apple)ambos podrían ser correctos dependiendo de la implementación de la is.elementfunción.
rileymcdowell
70

Agruparé las opciones según la salida. Suponga el siguiente vector para todos los ejemplos.

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

Para verificar la presencia:

%en%

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

ninguna()

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

is.element ()

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

Para encontrar la primera ocurrencia:

partido()

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

Para encontrar todas las ocurrencias como vector de índices:

cuales()

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

Para encontrar todas las ocurrencias como vector lógico :

==

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

Editar: Eliminar grep () y grepl () de la lista por la razón mencionada en los comentarios

ishandutta2007
fuente
66
Como ya comentamos aquí y aquí , no use grep()expresiones regulares para encontrar coincidencias exactas.
Uwe
69

La función any () crea un código legible

> 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
fuente
99
Tenga en cuenta que esto se comporta de manera diferente a %in%: any(1==NA)devuelve NA, donde 1 %in% NAdevuelve FALSE.
@ user3603486: any(1==NA, na.rm=TRUE)devoluciones FALSE.
AkselA
36

Puedes usar el %in%operador:

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

También para encontrar la posición del elemento "que" se puede utilizar como

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

which(pop==13)

y para encontrar los elementos que no están contenidos en el vector objetivo, uno puede hacer esto:

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

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

pop[which(!(pop%in%Tset))]
Armin
fuente
whichen realidad es preferible a veces porque le da todas las posiciones coincidentes (como una matriz), a diferencia match. Aunque esto quizás no fue lo que solicitó el OP, a diferencia de stackoverflow.com/questions/1169388/…
Fizz
2
¿Por qué molestarse whichsi solo quiere encontrar los elementos que no están en Tset? Puedes simplemente indexar popdirectamente; pop[!pop%in%Tset]
Houshalter
13

Realmente me gusta grep () y grepl () para este propósito.

grep () devuelve un vector de enteros, que indican dónde están las coincidencias.

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

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

grepl () devuelve un vector lógico, con "VERDADERO" en la ubicación de las coincidencias.

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

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

Estas funciones distinguen entre mayúsculas y minúsculas.

ojdajuiceman
fuente
10
Por defecto, greptoma una expresión regular como su primer elemento, por lo tanto, para hacer una coincidencia exacta "b", use^e$ o agregar , fixed=TRUE).
reinierpost
10
No use expresiones regulares para coincidencias exactas. Esto es peligroso y puede tener resultados inesperados
David Arenburg
99
Sí, esta es una idea terrible, no buena, muy mala, ineficiente y garantizada para romperse. Por ejemplo myvar <- 'blah'; grepl('b', myvar, fixed=TRUE), volveráTRUE aunque 'b' no esté dentro myvar.