R Language
Отказоустойчивый / устойчивый код
Поиск…
параметры
параметр | подробности |
---|---|
выраж | В случае успешного завершения «try part» tryCatch вернет последнее оцениваемое выражение . Следовательно, фактическое значение возвращается в случае, если все прошло хорошо, и нет условия (т.е. предупреждение или ошибка ) - это возвращаемое значение readLines . Обратите внимание, что вам не нужно объяснять состояние возвращаемого значения через return поскольку код в «try part» не завернут в оболочку функции (в отличие от обработчиков условий для предупреждений и ошибок ниже) |
предупреждение / ошибка / и т.д. | Предоставить / определить функцию обработчика для всех условий, которые вы хотите обработать явно. AFAIU, вы можете предоставить обработчики для любых условий (не только предупреждения и ошибки , но и пользовательские условия, см. simpleCondition и друзей для этого), если имя соответствующей функции обработчика соответствует классу соответствующего условия (см. Подробности части документа для tryCatch ). |
в конце концов | Здесь идет все, что должно быть выполнено в самом конце, независимо от того, выполнено ли выражение в «try part» или было ли какое-либо условие. Если вы хотите выполнить более одного выражения, то вам нужно обернуть их фигурными скобками, иначе вы могли бы просто написать finally = <expression> (т.е. та же логика, что и для «try part». |
замечания
tryCatch
tryCatch
возвращает значение, связанное с выполнением expr
если есть условие: предупреждение или ошибка. Если это так, конкретные возвращаемые значения (например, return(NA)
выше) могут быть заданы путем предоставления функции обработчика для соответствующих условий (см. Аргументы warning
и error
в ?tryCatch
). Это могут быть уже существующие функции, но вы также можете определить их в tryCatch
(как мы это делали выше).
Последствия выбора конкретных возвращаемых значений функций обработчика
Поскольку мы указали, что NA
должно быть возвращено в случае ошибки в «try part», третьим элементом в y
является NA
. Если бы мы выбрали NULL
как возвращаемое значение, длина y
бы равна 2
вместо 3
как lapply
будет просто «игнорировать / отбрасывать» возвращаемые значения, которые являются NULL
. Также обратите внимание, что если вы не укажете явное возвращаемое значение через return
, функции обработчика вернут NULL
(т.е. в случае ошибки или условия предупреждения ).
Предупреждение "Нежелательное"
Когда третий элемент нашего вектора urls
попадает в нашу функцию, мы получаем следующее предупреждение в дополнение к тому, что возникает ошибка ( readLines
сначала жалуется, что он не может открыть соединение с помощью предупреждения до фактического сбоя с ошибкой ):
Warning message:
In file(con, "r") : cannot open file 'I'm no URL': No such file or directory
Ошибка «выигрывает» над предупреждением , поэтому мы действительно не заинтересованы в предупреждении в этом конкретном случае. Таким образом, мы установили warn = FALSE
в readLines
, но это, похоже, не имеет никакого эффекта. Альтернативный способ подавления предупреждения - использовать
suppressWarnings(readLines(con = url))
вместо
readLines(con = url, warn = FALSE)
Использование tryCatch ()
Мы определяем надежную версию функции, которая считывает код HTML с заданного URL-адреса. Надежный в том смысле, что мы хотим, чтобы он справлялся с ситуациями, когда что-то либо ошибочно (ошибка), либо не совсем так, как мы планировали это (предупреждение). Зонный термин для ошибок и предупреждений является условием
Определение функции с помощью tryCatch
readUrl <- function(url) {
out <- tryCatch(
########################################################
# Try part: define the expression(s) you want to "try" #
########################################################
{
# Just to highlight:
# If you want to use more than one R expression in the "try part"
# then you'll have to use curly brackets.
# Otherwise, just write the single expression you want to try and
message("This is the 'try' part")
readLines(con = url, warn = FALSE)
},
########################################################################
# Condition handler part: define how you want conditions to be handled #
########################################################################
# Handler when a warning occurs:
warning = function(cond) {
message(paste("Reading the URL caused a warning:", url))
message("Here's the original warning message:")
message(cond)
# Choose a return value when such a type of condition occurs
return(NULL)
},
# Handler when an error occurs:
error = function(cond) {
message(paste("This seems to be an invalid URL:", url))
message("Here's the original error message:")
message(cond)
# Choose a return value when such a type of condition occurs
return(NA)
},
###############################################
# Final part: define what should happen AFTER #
# everything has been tried and/or handled #
###############################################
finally = {
message(paste("Processed URL:", url))
message("Some message at the end\n")
}
)
return(out)
}
Тестирование
Давайте определим вектор URL-адресов, где один элемент не является допустимым URL-адресом
urls <- c(
"http://stat.ethz.ch/R-manual/R-devel/library/base/html/connections.html",
"http://en.wikipedia.org/wiki/Xz",
"I'm no URL"
)
И передайте это как вход в функцию, определенную выше
y <- lapply(urls, readUrl)
# Processed URL: http://stat.ethz.ch/R-manual/R-devel/library/base/html/connections.html
# Some message at the end
#
# Processed URL: http://en.wikipedia.org/wiki/Xz
# Some message at the end
#
# URL does not seem to exist: I'm no URL
# Here's the original error message:
# cannot open the connection
# Processed URL: I'm no URL
# Some message at the end
#
# Warning message:
# In file(con, "r") : cannot open file 'I'm no URL': No such file or directory
Исследование выхода
length(y)
# [1] 3
head(y[[1]])
# [1] "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"
# [2] "<html><head><title>R: Functions to Manipulate Connections</title>"
# [3] "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"
# [4] "<link rel=\"stylesheet\" type=\"text/css\" href=\"R.css\">"
# [5] "</head><body>"
# [6] ""
y[[3]]
# [1] NA