Catching with tryCatch()
Part of the Logic & Flow section of Coddy's R journey. Lesson 53 of 64.
tryCatch(expr, error = function(e) ...) runs expr. If it raises an error, the handler runs instead and its value becomes the result, and the script continues:
safe_sqrt <- function(x) {
tryCatch(sqrt(x), error = function(e) NA)
}
print(safe_sqrt(16))
print(safe_sqrt("a"))
print("still running")Output:
[1] 4
[1] NA
[1] "still running"The handler receives the error as e, and conditionMessage(e) returns its message text:
result <- tryCatch(
stop("file not found"),
error = function(e) paste("Problem:", conditionMessage(e))
)
print(result)Output:
[1] "Problem: file not found"Wrap only the call that can fail, and catch it where you can do something useful, such as a default value or a message for the user:
to_number <- function(s) {
tryCatch({
if (s == "") stop("empty input")
as.integer(s)
}, error = function(e) -1L)
}
print(to_number("42"))
print(to_number(""))Output:
[1] 42
[1] -1In a loop, tryCatch() lets one bad item fail while the others are still processed:
inputs <- list(4, "x", 9)
for (v in inputs) {
r <- tryCatch(sqrt(v), error = function(e) "not a number")
cat(format(v), "->", r, "\n")
}Output:
4 -> 2
x -> not a number
9 -> 3 Challenge
EasyComplete safe_divide(a, b). Use tryCatch(): inside it, raise the error division by zero when b is 0 and otherwise compute a / b. The handler returns Error: followed by the message. Return the result rounded to two decimals as text, 3.33, or the error text.
The supplied code reads pairs of numbers such as 10/3, separated by commas, and prints the result of each pair on its own line.
Try it yourself
safe_divide <- function(a, b) {
# Write your code here
""
}
# Supplied input/output code: keep it as it is
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 = "")
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Logic & Flow
1Strings In Depth
Substrings with substr()Formatting with sprintf()Splitting and JoiningSearching StringsReplacing TextRecap - Username Builder4Matrices
Creating MatricesIndexing MatricesRow and Column SummariesMatrix ArithmeticRecap - Seating Chart2Key-Value Lookups
Named Vector LookupsChecking KeysAdding and Removing KeysLooping Over NamesRecap - Stock Desk8Sorting and Grouping
Sorting VectorsSorting by a KeyGrouping with split()Group SummariesRecap - Leaderboard11Error Handling
Raising Errors with stop()Catching with tryCatch()Warnings and finallyValidating InputRecap - Safe Calculator3Sets and Counting
Unique ValuesSet OperationsMembership TestsCounting with table()Recap - Event Guests6Functions as Values
Anonymous FunctionsPassing FunctionsReturning FunctionsClosures with StateRecap - Discount Rules9Data Frames
Creating Data FramesColumns and RowsFiltering RowsAdding and SortingRecap - Sales Report12Project - Expense Tracker
Recording ExpensesTotal SpendingPractice on your own: Online R compiler