Probar si un vector contiene un elemento dado


518

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


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

¿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

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


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

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

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

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.


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.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.