2011-06-01 12 views
14

Busco una manera elegante de regresar de nuevo las referencias que utilizan expresiones regulares en R. Le explico:¿Cómo puedo usar referencias anteriores con `grep` en R?

Digamos que quiero encontrar cadenas que comienzan con un nombre de mes:

x <- c("May, 1, 2011", "30 June 2011") 
grep("May|^June", x, value=TRUE) 
[1] "May, 1, 2011" 

Estos trabajos , pero realmente desee aislar el mes (es decir, "mayo", no toda la cadena coincidente

Por lo tanto, se puede utilizar gsub para devolver la referencia hacia atrás utilizando el parámetro substitute pero esto tiene dos problemas:..

  1. Tienes que envolver el patrón dentro de ". * (Patrón). *)" Para que la sustitución se produzca en toda la cadena.
  2. En lugar de devolver NA para cadenas no coincidentes, gsub devuelve la cadena original. Esto claramente no es lo que deseo:

el código y los resultados:

gsub(".*(^May|^June).*", "\\1", x) 
[1] "May"   "30 June 2011" 

probablemente podría codificar una solución haciendo todo tipo de comprobaciones adicionales, pero esto rápidamente se convierte en muy desordenado.

Para ser muy claro, los resultados deseados deben ser:

[1] "May"   NA 

¿Hay una manera fácil de lograr esto?

Respuesta

8

stringr El paquete tiene una función exactamente para este propósito:

library(stringr) 
x <- c("May, 1, 2011", "30 June 2011", "June 2012") 
str_extract(x, "May|^June") 
# [1] "May" NA  "June" 

Es un envoltorio bastante delgada alrededor regexpr, pero stringr hace generalmente más fácil el manejo de la cadena por ser más consistente que las funciones de base R.

+1

Gracias, Hadley. Soy un gran fan de stringr en general. No tengo idea de por qué no pensé en buscar allí primero. D'oh. – Andrie

20

regexpr es similar a grep, pero devuelve la posición y la longitud de la (primera) partido en cada cadena:

> x <- c("May, 1, 2011", "30 June 2011", "June 2012") 
> m <- regexpr("May|^June", x) 
> m 
[1] 1 -1 1 
attr(,"match.length") 
[1] 3 -1 4 

Esto significa que la primera cadena tenía un partido de la longitud 3 mirando en la posición 1, la segunda cadena tenido ninguna coincidencia, y la tercera cuerda tenido un partido de longitud 4 en la posición 1.

Para extraer los partidos, podría utilizar algo como:

> m[m < 0] = NA 
> substr(x, m, m + attr(m, "match.length") - 1) 
[1] "May" NA  "June" 
+0

Una gran sugerencia, gracias. Al final, decidí aceptar la respuesta de Hadley, simplemente porque es más elegante. – Andrie

+0

@NPE genial para ver cómo se hace con la base R – mcheema

3

El paquete gsubfn es más general que las funciones grep y regexpr y tiene formas de devolver las referencias inversas, consulte la función de aplicación.

+1

Pruebe esto: 'library (gsubfn); strapply (x, "^ (mayo | junio)") '. –

Cuestiones relacionadas