2010-04-07 16 views
26

Tengo una función de ejemplo a continuación que se lee en una fecha como una cadena y la devuelve como un objeto de fecha. Si lee una cadena que no puede convertir a una fecha, devuelve un error.¿Cómo decirle a lapply que ignore un error y procese lo siguiente en la lista?

testFunction <- function (date_in) { 
    return(as.Date(date_in)) 
    } 

testFunction("2010-04-06") # this works fine 
testFunction("foo") # this returns an error 

Ahora, quiero utilizar lapply y aplicar esta función a través de una lista de fechas:

dates1 = c("2010-04-06", "2010-04-07", "2010-04-08") 
lapply(dates1, testFunction) # this works fine 

Pero si quiero aplicar la función a través de una lista cuando una cuerda en medio de dos buenas fechas devuelve un error, ¿cuál es la mejor manera de lidiar con esto?

dates2 = c("2010-04-06", "foo", "2010-04-08") 
lapply(dates2, testFunction) 

Supongo que quiero un intento de captura en ese país, pero hay una manera de detectar el error de la cadena "foo", mientras que pide lapply para continuar y leer la tercera fecha?

+1

muy estrechamente relacionados: http://stackoverflow.com/questions/1395622/debugging-lapply-sapply-calls – Shane

Respuesta

44

utilizar una expresión tryCatch alrededor de la función que puede generar el mensaje de error:

testFunction <- function (date_in) { 
    return(tryCatch(as.Date(date_in), error=function(e) NULL)) 
} 

Lo bueno de la función tryCatch es que se puede decidir qué hacer en el caso de un error (en este caso , return NULL).

> lapply(dates2, testFunction) 
[[1]] 
[1] "2010-04-06" 

[[2]] 
NULL 

[[3]] 
[1] "2010-04-08" 
+0

Al final del día, los dos estamos haciendo lo mismo aquí - y John no necesita manejo de excepciones. Si no es una fecha, se devuelve NA. ¿Por qué hacer las cosas más difíciles? –

+1

Sí, eso es cierto en este caso.Aunque si la pregunta es generalizada, entonces usar 'tryCatch' es probablemente la mejor manera de continuar con un error en' lapply'. Creo que el ejemplo de la fecha fue solo un ejemplo. – Shane

+0

Gracias Dirk y Shane, en realidad el manejo de excepciones es lo que estaba buscando. Las fechas eran solo un ejemplo de una función más complicada, pero era lo más fácil que podía pensar que devolvería un error de una lista de cosas. – John

6

Se podría tratar de mantener la sencillez en lugar de hacerlo complicado:

  • Utilice el análisis sintáctico fecha vectorizado
R> as.Date(c("2010-04-06", "foo", "2010-04-08")) 
[1] "2010-04-06" NA   "2010-04-08" 

trivialmente Usted puede envolver na.omit() o lo que sea a su alrededor. O encuentre el índice de NA y extraiga en consecuencia del vector inicial, o use el complemento de las NA para encontrar las fechas analizadas, o, o, o. Ya está todo aquí.

  • Usted puede hacer su testFunction() hacer algo. Use la prueba allí: si la fecha devuelta (analizada) es NA, haga algo.

  • Agregue un bloque tryCatch() o try() al análisis de su fecha.

Las cosas conjunto es un poco extraño ya que se pasa de una estructura de datos de un solo tipo (vector de caracteres) a otra cosa, pero no se pueden mezclar fácilmente los tipos a menos que los mantienen en un tipo list. Entonces quizás necesites repensar esto.

0

Asumiendo que el testFunction() no es trivial y/o que no se puede modificar, se puede envolver en una función propia, con un bloque tryCatch(). Por ejemplo:

> FaultTolerantTestFunction <- function(date_in) { 
+ tryCatch({ret <- testFunction(date_in);}, error = function(e) {ret <<- NA}); 
+ ret 
+ } 
> FaultTolerantTestFunction('bozo') 
[1] NA 
> FaultTolerantTestFunction('2010-03-21') 
[1] "2010-03-21" 
Cuestiones relacionadas