Есть ли у кого-нибудь примеры/учебники по обработке исключений в R? Официальная документация очень краткая.
Обработка исключений в R
Ответ 1
Помимо ответа Shane, указывающего на другие обсуждения StackOverflow, вы можете попробовать функцию поиска кода. Этот оригинальный ответ указал на Google Code Search с тех пор был прекращен, но вы можете попробовать
- Поиск Github, например. в этот запрос для tryCatch в языке = R;
- Поиск кода Ohloh/Blackduck, например этот запрос для tryCatch в файлах R файла
- поисковая система кода Debian поверх всего архива Debian
Только для записи есть также 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
).