Function Errors

dplyr column not found

Matches: Can't find column|Column .* doesn't exist

WHAT THIS ERROR MEANS

dplyr can't find a column you referenced by name. This usually means a typo or the column was removed in a prior step.

WHY IT HAPPENS — 4 COMMON CAUSES

1. An earlier stage dropped the column

select() keeps only what you name, and summarise() keeps only the grouping variables plus what it computes. Both silently discard everything else, so a column present in the source data can be gone by the time the failing verb runs.

2. A rename happened upstream

rename(), janitor::clean_names() and the .names argument of across() all change column names mid-pipeline. clean_names() in particular rewrites Total Revenue to total_revenue, which breaks any later reference to the original spelling.

3. The name differs from what you see

Names read from Excel and CSV often carry trailing spaces, non-breaking spaces, or a byte-order mark on the first column. These are invisible in the RStudio viewer but make the name a different string.

4. The column is being masked by an environment variable

Tidy evaluation looks in the data first and the calling environment second. If a local variable shares a column’s name, code can silently use the wrong one — and when the column really is absent, the error names something you can see defined in your session, which is confusing.

HOW TO DIAGNOSE WHICH ONE IT IS

  1. Run names(df) on the original data first to confirm the column exists at the start.
  2. Bisect the pipe: run it up to the first verb, then the second, checking names() at each stage until the column disappears.
  3. Insert a checkpoint mid-pipe without breaking it — df |> select(a, b) |> print() |> mutate(...) — or use dplyr::glimpse().
  4. Suspect invisible characters? dput(names(df)) prints the exact strings, escapes and all.
  5. Force a column lookup with .data$revenue to rule out an environment variable of the same name.

HOW TO FIX IT

1. Check available columns with names(df) or colnames(df).

2. Look for typos in the column name.

3. Make sure a prior step didn't rename or remove the column.

CODE EXAMPLES

BAD — THIS CAUSES THE ERROR
df %>% select(reveneu)  # typo
GOOD — CORRECT APPROACH
df %>% select(revenue)  # correct name

MORE SCENARIOS THAT TRIGGER THIS

summarise() dropped the columns you needed later

BAD
df |>
  group_by(region) |>
  summarise(total = sum(revenue)) |>
  mutate(margin = total / units)
# Error: object 'units' not found
GOOD
df |>
  group_by(region) |>
  summarise(total = sum(revenue), units = sum(units)) |>
  mutate(margin = total / units)

summarise() returns only the grouping variables and the summaries you asked for. Anything you need downstream has to be summarised too — there is no implicit carry-through.

Selecting columns that may or may not be present

BAD
df |> select(region, revenue, forecast)
# Error if forecast is missing from this month's extract
GOOD
df |> select(any_of(c("region", "revenue", "forecast")))

any_of() ignores names that are not present, while all_of() insists on every one. Use all_of() when a missing column is a genuine data error you want to catch, and any_of() for genuinely optional fields.

PACKAGE-SPECIFIC NOTES

The pronouns .data and .env exist precisely to disambiguate this. .data$revenue always means the column and errors if it is missing; .env$revenue always means the variable in the calling scope. Both are essential when writing functions that take column names as arguments, where you should also reach for {{ }} to embrace an argument, or the .data[[col]] form when the name arrives as a string. data.table reports a different message for the same situation, naming the column it could not find in the j expression.

FUNCTIONS WORTH KNOWING

names()glimpse()any_of()all_of()starts_with()rename()janitor::clean_names()

FREQUENTLY ASKED QUESTIONS

Why does the column show in View(df) but dplyr cannot find it?

Almost always an invisible character in the name — a trailing space, a non-breaking space from a web copy-paste, or a UTF-8 BOM on the first column of a CSV. dput(names(df)) reveals them. janitor::clean_names() normalises the lot in one step.

Should I use all_of() or any_of()?

all_of() errors when a named column is missing, which is what you want for required fields. any_of() skips missing names quietly, which suits optional ones. Bare character vectors without either are ambiguous and now warn.

How do I reference a column whose name is in a variable?

If the variable holds a string, use .data[[col_name]]. If you are writing a function whose caller passes a bare column name, embrace the argument with {{ col }} so tidy evaluation resolves it against the data.

Still stuck?

Paste your code in RChat and the AI will fix this error in context.

Try RChat Free →

RELATED FUNCTION ERRORS