Estoy usando lapply
para ejecutar una función compleja en una gran cantidad de elementos, y me gustaría guardar la salida de cada elemento (si corresponde) junto con las advertencias/errores que se produjeron para poder decir cuál artículo producido qué advertencia/error.¿Cómo guardo las advertencias y los errores como salida de una función?
Encontré una forma de detectar advertencias usando withCallingHandlers
(descrito aquí: https://stackoverflow.com/questions/4947528). Sin embargo, necesito detectar errores también. Puedo hacerlo envolviéndolo en un tryCatch
(como en el código a continuación), pero ¿hay una mejor manera de hacerlo?
catchToList <- function(expr) {
val <- NULL
myWarnings <- NULL
wHandler <- function(w) {
myWarnings <<- c(myWarnings, w$message)
invokeRestart("muffleWarning")
}
myError <- NULL
eHandler <- function(e) {
myError <<- e$message
NULL
}
val <- tryCatch(withCallingHandlers(expr, warning = wHandler), error = eHandler)
list(value = val, warnings = myWarnings, error=myError)
}
Salida de ejemplo de esta función es:
> catchToList({warning("warning 1");warning("warning 2");1})
$value
[1] 1
$warnings
[1] "warning 1" "warning 2"
$error
NULL
> catchToList({warning("my warning");stop("my error")})
$value
NULL
$warnings
[1] "my warning"
$error
[1] "my error"
hay varias preguntas aquí en la SO que discuten tryCatch
y manejo de errores, pero ninguno que me encontré con que abordar esta cuestión en particular. Consulte How can I check whether a function call results in a warning?, warnings() does not work within a function? How can one work around this? y How to tell lapply to ignore an error and process the next thing in the list? para obtener los más relevantes.
Sí, la misma idea, pero mucho mejor! ¿Has considerado envolverlo en un paquete? De las otras preguntas que vi aquí en SO, a otros les resultaría útil también. – Aaron
Tengo una función que almacena su llamada en la salida. Después de invocar 'factory', esta llamada se cambia, p. 'fun (fórmula = ..1, data = ..2, method =" genetic ", ratio = ..4, print.level = 0)', donde 'formula' debería ser mi fórmula de entrada original, pero se sobrescribe . ¿Algun consejo? –
@ RomanLuštrik: Supongo que es porque en realidad está 'divirtiendo' una función nueva y llamándola con '...' en lugar de llamar directamente a la suya. Me pregunto si mi función 'catchToList' funciona, o si la' fábrica' podría modificarse, quizás usando 'do.call'. ¿Cómo se puede reproducir? – Aaron