Подтвердить что ты не робот

Обработка исключений в R

Есть ли у кого-нибудь примеры/учебники по обработке исключений в R? Официальная документация очень краткая.

4b9b3361

Ответ 1

Помимо ответа Shane, указывающего на другие обсуждения StackOverflow, вы можете попробовать функцию поиска кода. Этот оригинальный ответ указал на Google Code Search с тех пор был прекращен, но вы можете попробовать

Только для записи есть также try, но tryCatch может быть предпочтительным. Я попытался быстро подсчитать в Google Code Search, но попытаюсь получить слишком много ложных срабатываний для самого глагола, но, похоже, более широко используется tryCatch.

Ответ 2

В основном вы хотите использовать функцию 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")) 

Посмотрите на эти связанные вопросы:

Ответ 3

Этот результат от связанного поиска Google помог мне: http://biocodenv.com/wordpress/?p=15.

for(i in 1:16){
result <- try(nonlinear_modeling(i));
if(class(result) == "try-error") next;
}

Ответ 4

Функция перезапуска очень важна в 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(){})

Ответ 5

Функция trycatch() довольно проста, и есть много хороших руководств по этому поводу. Отличное объяснение обработки ошибок в R можно найти в книге Хэдли Уикхэма Advanced-R, а следующая - very базовое введение в 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. Он знает, что код низкого уровня выдает a 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 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).