library(tidyverse)
holdings <- tibble(
company = c("A Ltd", "B Ltd", "C Ltd"),
market_value_nok = c(120, 80, 100)
)Appendix C — Debugging
C.1 When code does not work
Errors are a normal part of learning R. The goal is not to memorize every message. It is to follow the same small set of checks each time.
C.2 Errors, warnings, and messages
- An error stops the code.
- A warning allows the code to finish but reports a possible problem.
- A message gives information about what a function did.
- An unexpected result may appear without any warning, so always inspect the output.
Read the final line of an error and identify the object, column, or function it mentions. Do not add several new functions at once in the hope that the error will disappear.
C.3 A simple debugging routine
- Run the code again and read the complete message.
- Check the spelling and capitalization of object and column names.
- Confirm that the required package was loaded.
- Inspect the table with
glimpse(). - Run one pipeline step at a time.
- Change one thing, then run the code again.
C.4 Example: a column name is wrong
This code asks for a column that does not exist:
holdings |>
arrange(desc(market_value))Error in `arrange()`:
ℹ In argument: `..1 = market_value`.
Caused by error:
! object 'market_value' not found
glimpse() shows the exact column names:
glimpse(holdings)Rows: 3
Columns: 2
$ company <chr> "A Ltd", "B Ltd", "C Ltd"
$ market_value_nok <dbl> 120, 80, 100
Make the smallest correction:
holdings |>
arrange(desc(market_value_nok))C.5 Example: find the first bad step
Break a longer pipeline into small objects:
step_1 <- holdings |>
filter(market_value_nok >= 100)
step_2 <- step_1 |>
mutate(value_millions = market_value_nok / 1000000)
step_1step_2The code runs, but the second result is unexpectedly small. The toy values were not measured in full kroner. This is a unit problem, not a syntax problem. Code that runs can still be wrong.
C.6 Check missing values with familiar functions
Use summarise() to display simple checks. is.na() identifies missing values, so sum(is.na(company)) counts missing company names:
holdings |>
summarise(
rows = n(),
missing_company_names = sum(is.na(company)),
smallest_value = min(market_value_nok)
)The expected results are three rows, no missing company names, and a positive smallest value. A useful check begins with a reasonable expectation about the source.
C.7 Ask for help effectively
Include:
- what you expected;
- what happened;
- the exact error or warning;
- the smallest example that reproduces it; and
- the packages being used.
Do not share confidential data or passwords when asking for help.
C.8 Practice
Find and correct the two problems in this code:
story <- tibble(
outlet = c("A", "B", "C"),
articles = c(12, NA, 20)
)
story |>
filter(Article >= 15) |>
summarise(average = mean(articles))Error in `filter()`:
ℹ In argument: `Article >= 15`.
Caused by error:
! object 'Article' not found
Explain the column-name problem and decide how the missing value should be handled. Do not add na.rm = TRUE until you can explain what the NA means.
C.9 Takeaways
| Practice | Why it helps |
|---|---|
| Read the message | Identifies the immediate problem |
| Check spelling and case | Finds many object and column errors |
glimpse() |
Shows names, types, and example values |
| Run one step at a time | Locates the first step that changes unexpectedly |
| Change one thing | Makes cause and effect easier to understand |
| Display simple checks | Catches results that are possible in R but implausible in the story |