Używam lapply
do uruchamiania złożonej funkcji na dużej liczbie elementów i chciałbym zapisać wynik każdego elementu (jeśli taki jest) wraz z wszelkimi ostrzeżeniami/błędami, które zostały wygenerowane, aby móc stwierdzić, które wyprodukowana pozycja z ostrzeżeniem/błędem.Jak zapisywać ostrzeżenia i błędy jako dane wyjściowe z funkcji?
Znalazłem sposób na złapanie ostrzeżeń za pomocą withCallingHandlers
(opisany tutaj: https://stackoverflow.com/questions/4947528). Jednak muszę też wychwycić błędy. Mogę to zrobić, zawijając go w tryCatch
(jak w poniższym kodzie), ale czy jest lepszy sposób na zrobienie tego?
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)
}
Przykładowe wyjście z tej funkcji jest następująca:
> 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"
Istnieje kilka pytania tutaj na SO, że dyskutować tryCatch
i obsługę błędów, ale nie że stwierdziliśmy, że rozwiązania tego konkretnego problemu. Zobacz 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? i How to tell lapply to ignore an error and process the next thing in the list? dla najbardziej odpowiednich.
Tak, ten sam pomysł, ale o wiele ładniejszy! Czy rozważałeś zawinięcie go do paczki? Z innych pytań, które zobaczyłem właśnie tutaj, dla innych osób również byłoby to przydatne. – Aaron
Mam funkcję, która przechowuje wywołanie w danych wyjściowych. Po wywołaniu 'fabryki' to połączenie zostanie zmienione, np. 'zabawa (formuła = ..1, dane = ..2, metoda =" genetyczne ", stosunek = ..4, print.level = 0)', gdzie 'formuła' powinna być moją oryginalną formułą wejściową, ale zostanie nadpisana . Jakieś wskazówki? –
@ RomanLuštrik: Zgaduję, że to dlatego, że w rzeczywistości tworzy nową funkcję "fun" i wywołuje ją za pomocą '...' zamiast dzwonić bezpośrednio. Zastanawiam się, czy działa funkcja 'catchToList', czy też' fabryka' może być modyfikowana, być może używając 'do.call'. Jak można go reprodukować? – Aaron