Перехват ошибок с помощью tryCatch()
Часть раздела Логика и потоки выполнения путешествия по R на Coddy. Урок 53 из 64.
tryCatch(expr, error = function(e) ...) выполняет expr. Если возникает ошибка, вместо него запускается обработчик, и его значение становится результатом, а выполнение скрипта продолжается:
safe_sqrt <- function(x) {
tryCatch(sqrt(x), error = function(e) NA)
}
print(safe_sqrt(16))
print(safe_sqrt("a"))
print("still running")Результат:
[1] 4
[1] NA
[1] "still running"Обработчик получает ошибку как e, а conditionMessage(e) возвращает её текст сообщения:
result <- tryCatch(
stop("file not found"),
error = function(e) paste("Problem:", conditionMessage(e))
)
print(result)Вывод:
[1] "Problem: file not found"Оборачивай только тот вызов, который может завершиться ошибкой, и перехватывай её там, где ты можешь сделать что-то полезное, например вернуть значение по умолчанию или вывести сообщение для пользователя:
to_number <- function(s) {
tryCatch({
if (s == "") stop("empty input")
as.integer(s)
}, error = function(e) -1L)
}
print(to_number("42"))
print(to_number(""))Результат:
[1] 42
[1] -1В цикле tryCatch() позволяет одному ошибочному элементу завершиться с ошибкой, пока остальные по-прежнему обрабатываются:
inputs <- list(4, "x", 9)
for (v in inputs) {
r <- tryCatch(sqrt(v), error = function(e) "not a number")
cat(format(v), "->", r, "\n")
}Вывод:
4 -> 2
x -> not a number
9 -> 3 Задание
ЛегкоЗавершите safe_divide(a, b). Используйте tryCatch(): внутри него вызовите ошибку division by zero, когда b равно 0, а в противном случае вычислите a / b. Обработчик возвращает Error: , за которым следует сообщение. Верните результат, округлённый до двух знаков после запятой, в виде текста, например 3.33, или текст ошибки.
Предоставленный код считывает пары чисел, такие как 10/3, разделённые запятыми, и выводит результат для каждой пары в отдельной строке.
Попробуйте сами
safe_divide <- function(a, b) {
# Напишите ваш код здесь
""
}
# Предоставленный код ввода/вывода: оставьте его как есть
input <- suppressWarnings(readLines(file("stdin")))
for (pair in strsplit(input[1], ",")[[1]]) {
p <- as.numeric(strsplit(pair, "/")[[1]])
cat(safe_divide(p[1], p[2]), "\n", sep = "")
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и потоки выполнения
1Строки углублённо
Подстроки с substr()Форматирование с sprintf()Разделение и объединениеПоиск в строкахЗамена текстаПовторение — создание имени пользователя4Матрицы
Создание матрицИндексация матрицСводные данные по строкам и столбцамАрифметика матрицПовторение — схема рассадки7Семейство Apply
lapply и sapplyMap и mapplyFilter и FindReduceПовторение — конвейер обработки данных10Продвинутые конструкции управления
Функция switch()Векторизованный ifelse()repeat и breakРекурсивные функцииПовторение — классификатор оценок2Поиск по ключам и значениям
Поиск в именованных векторахПроверка ключейДобавление и удаление ключейПеребор имёнПовторение — биржа акций5Проект — Журнал оценок
Добавление учениковВыставление оценок8Сортировка и группировка
Сортировка векторовСортировка по ключуГруппировка с помощью split()Итоги по группамПовторение — таблица лидеров11Обработка ошибок
Генерация ошибок с помощью stop()Перехват ошибок с помощью tryCatch()Предупреждения и finallyПроверка входных данныхПовторение — безопасный калькулятор3Множества и подсчёт
Уникальные значенияОперации с множествамиПроверка принадлежностиПодсчёт с помощью table()Повторение — гости мероприятия6Функции как значения
Анонимные функцииПередача функцийВозврат функцийЗамыкания с состояниемПовторение — правила скидок9Таблицы данных
Создание таблиц данныхСтолбцы и строкиФильтрация строкДобавление и сортировкаПовторение — отчёт о продажах12Проект — Трекер расходов
Запись расходовОбщие расходыПотренируйтесь самостоятельно: Онлайн-компилятор R