Estoy tratando de determinar si una cadena es un subconjunto de otra cadena. Por ejemplo:
chars <- "test"
value <- "es"
Quiero devolver VERDADERO si "valor" aparece como parte de la cadena "caracteres". En el siguiente escenario, me gustaría devolver falso:
chars <- "test"
value <- "et"
fixed=TRUE
, de lo contrario, la trata como una expresión regular en lugar de una cadena. Vea mi respuesta de octubre de 2016.fixed=TRUE
o tiene un error que desordenará sus datos de manera silenciosa y sutil.Respuestas:
Usa la
grepl
funciónUse
?grepl
para descubrir más.fuente
vec <- replicate(100000, paste( sample(letters, 10, replace=TRUE), collapse='') )
.system.time(a <- grepl("abc", vec))
ysystem.time(a <- grepl("abc", vec, fixed=TRUE))
, yfixed=TRUE
sigue siendo, si algo algo más lento. La diferencia no es apreciable con estas cadenas cortas, perofixed=TRUE
aún así no parece ser más rápida. Gracias por señalar, sin embargo, que son las cuerdas largas las quefixed=TRUE
toman el golpe real.Responder
Suspiro, me tomó 45 minutos encontrar la respuesta a esta simple pregunta. La respuesta es:
grepl(needle, haystack, fixed=TRUE)
Interpretación
grep
lleva el nombre del ejecutable de Linux, que en sí es un acrónimo de " G lobal R egular E Xpression P rint", se leería las líneas de entrada y luego imprimirlos si coincide con los argumentos que diste. "Global" significa que la coincidencia podría ocurrir en cualquier lugar de la línea de entrada, explicaré "Expresión regular" a continuación, pero la idea es que es una forma más inteligente de hacer coincidir la cadena (R llama a este "carácter", por ejemploclass("abc")
) e "Imprimir "debido a que es un programa de línea de comando, la emisión de salida significa que se imprime en su cadena de salida.Ahora, el
grep
programa es básicamente un filtro, desde líneas de entrada hasta líneas de salida. Y parece que lagrep
función de R de manera similar tomará una serie de entradas. Por razones completamente desconocidas para mí (solo comencé a jugar con R hace aproximadamente una hora), devuelve un vector de los índices que coinciden, en lugar de una lista de coincidencias.Pero, volviendo a su pregunta original, lo que realmente queremos es saber si encontramos la aguja en el pajar, un valor verdadero / falso. Al parecer, decidieron llamar a esta función
grepl
, como en "grep" pero con una " L valor de retorno gico" (que ellos llaman valores lógicos verdadero y falso, por ejemploclass(TRUE)
).Entonces, ahora sabemos de dónde viene el nombre y qué se supone que debe hacer. Volvamos a las expresiones regulares. Los argumentos, aunque son cadenas, se usan para construir expresiones regulares (en adelante: regex). Una expresión regular es una forma de hacer coincidir una cadena (si esta definición te irrita, déjalo ir). Por ejemplo, la expresión regular
a
coincide con el carácter"a"
, la expresión regulara*
coincide con el carácter"a"
0 o más veces, y la expresión regulara+
coincidirá con el carácter"a"
1 o más veces. Por lo tanto, en el ejemplo anterior, la aguja que estamos buscando1+2
, cuando se trata como una expresión regular, significa "uno o más 1 seguido de un 2" ... ¡pero al nuestro le sigue un signo más!Entonces, si usó la
grepl
configuración sin configuraciónfixed
, sus agujas accidentalmente serían pajares, y eso funcionaría accidentalmente con bastante frecuencia, podemos ver que incluso funciona para el ejemplo del OP. Pero eso es un error latente! Necesitamos decirle que la entrada es una cadena, no una expresión regular, que aparentementefixed
es para lo que sirve. ¿Por qué arreglado? No tengo idea, marque esta respuesta b / c, probablemente tendrá que buscarla 5 veces más antes de memorizarla.Algunas reflexiones finales
Cuanto mejor sea su código, menos historia tendrá que saber para darle sentido. Cada argumento puede tener al menos dos valores interesantes (de lo contrario, no necesitaría ser un argumento), los documentos enumeran 9 argumentos aquí, lo que significa que hay al menos 2 ^ 9 = 512 formas de invocarlo, eso es mucho trabajo para escribir, probar y recordar ... desacoplar tales funciones (dividirlas, eliminar dependencias entre sí, las cosas de cadena son diferentes a las cosas de expresiones regulares son diferentes a las cosas de vectores). Algunas de las opciones también son mutuamente excluyentes, no brindan a los usuarios formas incorrectas de usar el código, es decir, la invocación problemática debe ser estructuralmente sin sentido (como pasar una opción que no existe), no lógicamente sin sentido (donde debe emitir una advertencia para explicarlo). Poner metafóricamente: reemplazar la puerta de entrada en el costado del décimo piso con una pared es mejor que colgar un letrero que advierte contra su uso, pero cualquiera de los dos es mejor que ninguno. En una interfaz, la función define cómo deberían verse los argumentos, no la persona que llama (porque la persona que llama depende de la función, inferir todo con lo que todos quieran llamarla hace que la función también dependa de las personas que llaman, y este tipo de dependencia cíclica obstruirá rápidamente un sistema y nunca proporcionará los beneficios que espera). Tenga mucho cuidado con los tipos equívocos, es un defecto de diseño que cosas como inferir todo con lo que todos quieran llamarlo hace que la función también dependa de las personas que llaman, y este tipo de dependencia cíclica obstruirá rápidamente un sistema y nunca proporcionará los beneficios que espera). Tenga mucho cuidado con los tipos equívocos, es un defecto de diseño que cosas como inferir todo con lo que todos quieran llamarlo hace que la función también dependa de las personas que llaman, y este tipo de dependencia cíclica obstruirá rápidamente un sistema y nunca proporcionará los beneficios que espera). Tenga mucho cuidado con los tipos equívocos, es un defecto de diseño que cosas como
TRUE
y0
y"abc"
son todos vectores.fuente
grep
que filtrar filas, no celdas.Tu quieres
grepl
:fuente
Use esta función del
stringi
paquete:Algunos puntos de referencia:
fuente
Además, se puede hacer usando la biblioteca "stringr":
fuente
En caso de que también desee comprobar si una cadena (o un conjunto de cadenas) contiene varias subcadenas, también puede usar el '|' entre dos subcadenas.
Conseguirás
ya que la primera palabra tiene una subcadena "como", y la última palabra contiene la subcadena "en"
fuente
Use
grep
ogrepl
pero tenga en cuenta si desea o no usar expresiones regulares .Por defecto,
grep
y relacionado, toma una expresión regular para que coincida, no una subcadena literal. Si no espera eso e intenta hacer coincidir una expresión regular no válida, no funciona:Para hacer una verdadera prueba de subcadena, use
fixed = TRUE
.Si quieres expresiones regulares, genial, pero eso no es lo que parece estar preguntando el OP.
fuente
Puedes usar
grep
fuente
Problema similar aquí: dada una cadena y una lista de palabras clave, detecta cuál de las palabras clave, si las hay, está contenida en la cadena.
Las recomendaciones de este hilo sugieren
stringr
'sstr_detect
ygrepl
. Aquí están los puntos de referencia de lamicrobenchmark
paquete:Utilizando
y entonces
encontramos
Como puede ver, más de 5,000 iteraciones de la búsqueda de palabras clave usando
str_detect
ygrepl
sobre una cadena práctica y un vector de palabras clave, segrepl
desempeña bastante mejor questr_detect
.El resultado es el vector booleano
r
que identifica cuál de las palabras clave, si las hay, está contenida en la cadena.Por lo tanto, recomiendo usar
grepl
para determinar si alguna palabra clave está en una cadena.fuente