Skip to content
AgileLogics
5 min read

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

  1. Reproduce the problem reliably.
  2. Narrow it down — check the data at each step of the pipeline.
  3. Question assumptions — "that column is numeric" is often wrong.
  4. Fix it, and add a test so it can't come back.