¿Cómo decirle a lapply que ignore un error y procese lo siguiente en la lista?

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.

testFunction <- function (date_in) { return(as.Date(date_in)) } testFunction("2010-04-06") # this works fine testFunction("foo") # this returns an error 

Ahora, quiero usar lapply y aplicar esta función en 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 sobre una lista cuando una cadena 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 una captura de prueba allí, pero ¿hay alguna manera de detectar el error de la cadena “foo” mientras que pido continuar y leer la tercera fecha?

Use una expresión tryCatch alrededor de la función que puede arrojar 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 puede decidir qué hacer en caso de error (en este caso, devolver NULL ).

 > lapply(dates2, testFunction) [[1]] [1] "2010-04-06" [[2]] NULL [[3]] [1] "2010-04-08" 

Uno podría tratar de mantenerlo simple en lugar de hacerlo complicado:

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

Puedes envolver trivialmente na.omit() o lo que sea alrededor de él. 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í.

  • Puedes hacer que tu testFunction() haga 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.

Todo esto es un poco extraño a medida que pasa de una estructura de datos de un tipo (vector de caracteres) a otra cosa, pero no puede mezclar fácilmente tipos a menos que los mantenga en un tipo de list . Entonces quizás necesites repensar esto.

Asumiendo que testFunction() no es trivial y / o que uno no puede alterarlo, puede envolverlo 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"