Хтось має приклади / навчальні посібники з обробки винятків в 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(){})