使用 tryCatch() 捕获错误
本课属于 Coddy R 学习旅程的“逻辑与流程”单元。第 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():当 b 为 0 时,在其中引发 division by zero 错误,否则计算 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 = "")
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
逻辑与流程中的所有课
自己练习: R 在线编译器