2010-04-12 2 views
94

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

+1

Этот пример также является хорошим примером: http://stackoverflow.com/q/12193779/2026975. – imriss

+0

Я нашел это сообщение в блоге весьма полезным: [http://mazamascience.com/WorkingWithData/?p=912](http://mazamascience.com/WorkingWithData/?p=912) –

+0

Я запросил тему документации SO для этого вопроса. – Leonid

ответ

30

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

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

+0

Возможно, этот пример может помочь: [http://stackoverflow.com/a/12195574/2026975](http://stackoverflow.com/a/12195574/2026975) – imriss

+0

[Поиск по Github] (https: // github. com/search? q = tryCatch + language% 3AR & type = Code & ref = searchresults), вероятно, является достойной заменой несуществующей ссылки. – Gregor

58

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

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

+1

Третья ссылка не является ссылкой. – Marek

+8

Не ошибка Шейна - возможно, ошибка в регулярном выражении, определяющая, как разделить содержимое на SO. –

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(){}) 
6

Функция trycatch() довольно прямо вперед, и есть много хороших учебников по этому вопросу. Отличное объяснение обработки в R ошибки можно найти в книге Hadley Уикхем Advanced-R, и что следует, очень основное введение в withCallingHandlers() и withRestarts() в нескольких словах, как это возможно:

Допустит, программист низкого уровня пишет для вычисления абсолютного значения . Он не уверен, как вычислить его, но знает how to construct an error и старательно передает его наивность:

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).

Смежные вопросы