2012-04-18 9 views
6

Estoy usando la función gsub en R para devolver las apariciones de mi patrón (números de referencia) en una lista de texto. Esto funciona muy bien a menos que no se encuentre una coincidencia, en cuyo caso recupero toda la cadena, en lugar de una cadena vacía. Considere el ejemplo:gsub devuelve una cadena vacía cuando no se encuentra ninguna coincidencia

data <- list("a sentence with citation (Ref. 12)", 
      "another sentence without reference") 

sapply(data, function(x) gsub(".*(Ref. (\\d+)).*", "\\1", x)) 

devoluciones:

[1] "Ref. 12"       "another sentence without reference" 

Pero me gustaría llegar

[1] "Ref. 12"       "" 

Gracias!

+1

'gsub' no puede (actualmente, 2.15.0) hacer esto porque:" Si 'replacement' contiene referencias posteriores que no están definidas en' pattern' el resultado no está definido (pero lo más habitual es que la retro-referencia sea '" " ')." –

Respuesta

6

probablemente me vaya una ruta diferente, ya que no parece necesaria la sapply para mí ya que estas funciones ya están vectorizados:

fun <- function(x){ 
    ind <- grep(".*(Ref. (\\d+)).*",x,value = FALSE) 
    x <- gsub(".*(Ref. (\\d+)).*", "\\1", x) 
    x[-ind] <- "" 
    x 
} 

fun(data) 
+0

¿Alguna razón para usar 'grep' y no' grepl'? –

+0

@David No lo creo, es solo lo que mis dedos escribieron primero. – joran

0

Puede intentar incrustar grep(..., value = T) en esa función.

data <- list("a sentence with citation (Ref. 12)", 
     "another sentence without reference") 

unlist(sapply(data, function(x) { 
    x <- gsub(".*(Ref. (\\d+)).*", "\\1", x) 
    grep("Ref\\.", x, value = T) 
    })) 

¿Tipo de voluminoso pero funciona? También elimina la segunda referencia vacía.

+0

Funciona para mí. En mi caso dejaré de lado la lista, ya que aún quiero saber dónde están los datos faltantes. ¡Gracias! – cboettig

+0

@cboettig Tenga en cuenta que el 'sapply' es excesivo aquí. – joran

+0

@joran gracias, estaba simplificando el ejemplo de un caso que creo que necesitaba el sapply porque datos una lista de listas, olvidé que no lo necesitaba aquí. ;-) Eso es más agradable. – cboettig

2

según la documentación, esta es una característica de gsub vuelve la cadena de entrada si no hay coincidencias con las coincidencias de patrón suministradas devuelve la cadena completa.

aquí, utilizo la función grepl primeros en regresar un vector lógico de la presencia/ausencia del patrón en la cadena dada:

ifelse(grepl(".*(Ref. (\\d+)).*", data), 
     gsub(".*(Ref. (\\d+)).*", "\\1", data), 
     "") 

incrustación de esto en una función:

mygsub <- function(x){ 
    ans <- ifelse(grepl(".*(Ref. (\\d+)).*", x), 
       gsub(".*(Ref. (\\d+)).*", "\\1", x), 
       "") 
    return(ans) 
} 

mygsub(data) 
1
xs <- sapply(data, function(x) gsub(".*(Ref. (\\d+)).*", "\\1", x)) 
xs[xs==data] <- "" 
xs 
#[1] "Ref. 12" ""  
1

Probar strapplyc en el paquete gsubfn:

library(gsubfn) 

L <- fn$sapply(unlist(data), ~ strapplyc(x, "Ref. \\d+")) 
unlist(fn$sapply(L, ~ ifelse(length(x), x, ""))) 

que da a esta:

a sentence with citation (Ref. 12) another sentence without reference 
         "Ref. 12"         "" 

Si no le importa salida de la lista a continuación, sólo podría utilizar L y olvidarse de la última línea de código. Tenga en cuenta que el prefijo fn$ convierte los argumentos de la fórmula de la función a la que se aplica en llamadas a funciones para que la primera línea de código se pueda escribir sin fn como sapply(unlist(data), function(x) strapplyc(x, "Ref x. \\d+")).

+0

Nunca he visto 'fn $' usado, ¿dónde lo encontraste? –

+0

En el paquete gsubfn, vea '? Fn' y la sección 7 de la viñeta' gsubfn'. –

Cuestiones relacionadas