Czy ktoś ma przykłady / tutoriale obsługi wyjątków w R? Oficjalna dokumentacja jest bardzo zwięzła.
Czy ktoś ma przykłady / tutoriale obsługi wyjątków w R? Oficjalna dokumentacja jest bardzo zwięzła.
Odpowiedzi:
Oprócz odpowiedzi Shane'a wskazującej na inne dyskusje StackOverflow, możesz wypróbować funkcję wyszukiwania kodu. Ta pierwotna odpowiedź wskazała na wyszukiwarkę Google Code Search, która została wycofana, ale możesz spróbować
Tak dla przypomnienia, jest też, tryale tryCatchmoże być lepsze. Próbowałem szybko policzyć w Google Code Search, ale próbowałem uzyskać zbyt wiele fałszywych alarmów dla samego czasownika - ale wydaje się, że tryCatchjest on częściej używany.
Zasadniczo chcesz użyć tej tryCatch()funkcji. Więcej informacji znajdziesz w pomocy („tryCatch”).
Oto trywialny przykład (pamiętaj, że z błędem możesz zrobić, co chcesz):
vari <- 1
tryCatch(print("passes"), error = function(e) print(vari), finally=print("finished"))
tryCatch(stop("fails"), error = function(e) print(vari), finally=print("finished"))
Spójrz na te powiązane pytania:
Pomógł mi ten wynik z powiązanej wyszukiwarki Google: http://biocodenv.com/wordpress/?p=15 .
for(i in 1:16){
result <- try(nonlinear_modeling(i));
if(class(result) == "try-error") next;
}
Ta funkcja trycatch()jest dość prosta i jest na jej temat wiele dobrych tutoriali. Doskonałe wyjaśnienie obsługi błędów w R można znaleźć w książce Hadleya Wickhama Advanced-R , a poniżej znajduje się bardzo podstawowe wprowadzenie do withCallingHandlers()i withRestarts()w jak najmniejszej liczbie słów:
Powiedzmy, że programista niskiego poziomu pisze funkcję obliczającą wartość bezwzględną. Nie jest pewien, jak to obliczyć, ale wie, jak skonstruować błąd i pilnie przekazuje swoją naiwność:
low_level_ABS <- function(x){
if(x<0){
#construct an error
negative_value_error <- structure(
# with class `negative_value`
class = c("negative_value","error", "condition"),
list(message = "Not Sure what to with a negative value",
call = sys.call(),
# and include the offending parameter in the error object
x=x))
# raise the error
stop(negative_value_error)
}
cat("Returning from low_level_ABS()\n")
return(x)
}
Programista średniego poziomu pisze również funkcję obliczającą wartość bezwzględną, wykorzystując żałośnie niekompletną low_level_ABSfunkcję. Wie, że kod niskiego poziomu generuje negative_value
błąd, gdy wartość xjest ujemna, i sugeruje rozwiązanie problemu, ustanawiając sposób, restartktóry pozwala użytkownikom mid_level_ABSkontrolować sposób, w jaki mid_level_ABSodzyskuje (lub nie) po negative_valuebłędzie.
mid_level_ABS <- function(y){
abs_y <- withRestarts(low_level_ABS(y),
# establish a restart called 'negative_value'
# which returns the negative of it's argument
negative_value_restart=function(z){-z})
cat("Returning from mid_level_ABS()\n")
return(abs_y)
}
Wreszcie, programista wysoki poziom wykorzystuje mid_level_ABSfunkcję do obliczania wartości bezwzględnej, a ustanawia obsługi warunek, który mówi
mid_level_ABS, aby odzyskać od negative_valuebłędu za pomocą obsługi restartu.
high_level_ABS <- function(z){
abs_z <- withCallingHandlers(
# call this function
mid_level_ABS(z) ,
# and if an `error` occurres
error = function(err){
# and the `error` is a `negative_value` error
if(inherits(err,"negative_value")){
# invoke the restart called 'negative_value_restart'
invokeRestart('negative_value_restart',
# and invoke it with this parameter
err$x)
}else{
# otherwise re-raise the error
stop(err)
}
})
cat("Returning from high_level_ABS()\n")
return(abs_z)
}
Chodzi o to, że używając withRestarts()i withCallingHandlers(), funkcja
high_level_ABSbyła w stanie powiedzieć, mid_level_ABSjak naprawić błędy wywołane przez low_level_ABSbłąd bez zatrzymywania wykonywania
mid_level_ABS, czego nie można zrobić tryCatch():
> high_level_ABS(3)
Returning from low_level_ABS()
Returning from mid_level_ABS()
Returning from high_level_ABS()
[1] 3
> high_level_ABS(-3)
Returning from mid_level_ABS()
Returning from high_level_ABS()
[1] 3
W praktyce low_level_ABSreprezentuje funkcję, która mid_level_ABSwywołuje dużo (może nawet miliony razy), dla której poprawna metoda obsługi błędów może się różnić w zależności od sytuacji, a wybór sposobu obsługi określonych błędów pozostawia się funkcjom wyższego poziomu ( high_level_ABS).
Funkcja restartu jest bardzo ważna w R dziedziczonej z Lispa. Jest to przydatne, jeśli chcesz wywołać jakąś funkcję w treści pętli i chcesz, aby program kontynuował działanie, jeśli wywołanie funkcji się zwinie. Wypróbuj ten kod:
for (i in 1:20) withRestarts(tryCatch(
if((a <- runif(1))>0.5) print(a) else stop(a),
finally = print("loop body finished!")),
abort = function(){})