Обробка винятків у R [закрито]


97

Хтось має приклади / навчальні посібники з обробки винятків в R? Офіційна документація дуже лаконічна.


1
Цей також є хорошим прикладом: stackoverflow.com/q/12193779/2026975 .
imriss

Я вважаю цю публікацію в блозі дуже корисною: http://mazamascience.com/WorkingWithData/?p=912
paul_dg

Відповіді:


31

Окрім відповіді Шейна, яка вказує на інші дискусії StackOverflow, ви можете спробувати функцію пошуку коду. Ця оригінальна відповідь, яка вказує на пошук коду Google, з тих пір припинена, але ви можете спробувати

Для запису також є, tryале tryCatchможе бути кращим. Я спробував швидкий підрахунок у Google Code Search, але спробуйте отримати занадто багато хибних позитивних результатів для самого дієслова - але, здається, tryCatchвін широко використовується.


Можливо, цей приклад може допомогти: http://stackoverflow.com/a/12195574/2026975
imriss

Пошук Github , ймовірно , є гідною заміною для неіснуючої посилання.
Грегор Томас

Всі ланки розірвані.
Toros91

60

В основному ви хочете використовувати цю 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")) 

Погляньте на ці пов'язані питання:



8

Функція 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).


7

Функція перезапуску дуже важлива в 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(){})
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.