Debugging R Code
Prerequisites: Error handling and defensive code
Debugging is finding out why code doesn't do what you expect.
1. Read the error — and find where it happened
Error messages name the failing call. traceback() (run right after an
error) shows the chain of function calls that led to it:
> summarise_sales(sales)
Error in sum(x$amount) : invalid 'type' (character) of argument
> traceback()
3: summarise_sales(sales)
2: total_amount(df)
1: sum(x$amount)
Here, amount is text, not numbers — probably from importing a file with
a currency symbol in it. RStudio shows a Show Traceback button next to
errors.
2. Inspect the data
Most R bugs are data problems. Check your assumptions:
df <- data.frame(amount = c("10", "20", "n/a"))
str(df)
sum(is.na(suppressWarnings(as.numeric(df$amount))))
unique(df$amount[is.na(suppressWarnings(as.numeric(df$amount)))])
'data.frame': 3 obs. of 1 variable:
$ amount: chr "10" "20" "n/a"
[1] 1
[1] "n/a"
str(), summary(), unique(), table(), and head() answer most "why
is this wrong?" questions quickly.
3. Pause inside a function: browser()
Put browser() in a function; when it runs, execution pauses there and
you can inspect every variable in the console:
total_amount <- function(df) {
browser()
sum(df$amount)
}
At the Browse> prompt: n runs the next line, c continues, Q quits,
and typing a variable's name shows its value. In RStudio, clicking in the
margin next to a line number sets a breakpoint that does the same.
debugonce(fun) pauses the next time fun is called, without editing it.
4. Make a minimal example
Cut the problem down to the smallest code and data that still shows it —
a few rows made with data.frame() or dput(head(df)). Often, the bug
becomes obvious along the way; if not, a minimal example (a reprex) is
exactly what to share when asking for help. The reprex package
formats one for you.
A debugging process
- Reproduce the problem reliably.
- Narrow it down — check the data at each step of the pipeline.
- Question assumptions — "that column is numeric" is often wrong.
- Fix it, and add a test so it can't come back.