Хтось має приклади / навчальні посібники з обробки винятків в R? Офіційна документація дуже лаконічна.
Хтось має приклади / навчальні посібники з обробки винятків в R? Офіційна документація дуже лаконічна.
Відповіді:
Окрім відповіді Шейна, яка вказує на інші дискусії StackOverflow, ви можете спробувати функцію пошуку коду. Ця оригінальна відповідь, яка вказує на пошук коду Google, з тих пір припинена, але ви можете спробувати
Для запису також є, try
але tryCatch
може бути кращим. Я спробував швидкий підрахунок у Google Code Search, але спробуйте отримати занадто багато хибних позитивних результатів для самого дієслова - але, здається, tryCatch
він широко використовується.
В основному ви хочете використовувати цю tryCatch()
функцію. Щоб отримати докладнішу інформацію, перегляньте довідку ("tryCatch").
Ось тривіальний приклад (майте на увазі, що ви можете робити все, що завгодно, з помилкою):
vari <- 1
tryCatch(print("passes"), error = function(e) print(vari), finally=print("finished"))
tryCatch(stop("fails"), error = function(e) print(vari), finally=print("finished"))
Погляньте на ці пов'язані питання:
Цей результат, пов’язаний із пошуковим пошуком Google, допоміг мені: http://biocodenv.com/wordpress/?p=15 .
for(i in 1:16){
result <- try(nonlinear_modeling(i));
if(class(result) == "try-error") next;
}
Функція trycatch()
досить прямо вперед, і на цьому є багато хороших навчальних посібників. Відмінне пояснення поводження з помилками в R можна знайти в книзі Хедлі Вікхем Advanced-R , а далі - дуже базове вступ withCallingHandlers()
і withRestarts()
якомога менше слів:
Скажімо, програміст низького рівня записує функцію для обчислення абсолютного значення. Він не знає, як його обчислити, але знає, як побудувати помилку і старанно передає свою наївність:
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)
}
Програміст середнього рівня також пише функцію для обчислення абсолютного значення, використовуючи жахливо неповну low_level_ABS
функцію. Він знає, що код низького рівня видає negative_value
помилку, коли значення x
від'ємне, і пропонує рішення проблеми, встановивши, restart
що дозволяє користувачам mid_level_ABS
контролювати спосіб mid_level_ABS
відновлення (або ні) negative_value
помилки.
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)
}
Нарешті, програміст високого рівня використовує mid_level_ABS
функцію для обчислення абсолютного значення та встановлює обробник стану, який повідомляє
mid_level_ABS
відновитись після negative_value
помилки за допомогою обробника перезавантаження.
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)
}
Сенс всього цього в тому , що при використанні withRestarts()
і withCallingHandlers()
функція
high_level_ABS
була в змозі сказати , mid_level_ABS
як позбутися від помилок , піднятим low_level_ABS
помилки , не зупиняючи виконання
mid_level_ABS
, яке є те , що ви не можете зробити з 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
На практиці low_level_ABS
являє собою функцію, яка mid_level_ABS
викликає багато (можливо, навіть мільйони разів), для якої правильний метод поводження з помилками може відрізнятися залежно від ситуації, а вибір способу обробки певних помилок залишається функціям вищого рівня ( high_level_ABS
).
Функція перезапуску дуже важлива в R, успадкованому від Lisp. Це корисно, якщо ви хочете викликати якусь функцію в тілі циклу, і ви просто хочете, щоб програма продовжувалася, якщо виклик функції припиняється. Спробуйте цей код:
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(){})