Skip to Content
Course content
Click on the "Edit" button in the top corner of the screen to edit your slide content.

How do I grab a bunch of columns that follow a naming pattern without typing them all?

This is where you'll spend most of your time with tidyselect. When you're dealing with a dataset that has dozens of columns—like a climate dataset with temp_jan, temp_feb, temp_mar, and so on—typing every single name is a waste of your life. I usually reach for starts_with(), ends_with(), or contains().

# Let's say we have a dataframe called 'weather_df'
# I only want the temperature columns
weather_df %>% 
  select(starts_with("temp"))

# Or maybe I want everything related to January across different metrics
weather_df %>% 
  select(ends_with("_jan"))

One thing to keep in mind: these helpers are case-insensitive by default. If you have columns named Temp_Jan and temp_jan, starts_with("temp") will grab both. If you need to be strict, you can pass ignore.case = FALSE as a second argument. I rarely use it, but it's there if your naming convention is weirdly specific.

What's the difference between all_of() and any_of() when using a character vector?

You'll often run into a situation where your column names are stored in a variable—maybe a character vector you built dynamically. If you just throw that vector into select(), R sometimes gets confused about whether you're referring to a column name or the vector itself. That's why we use all_of() and any_of().

target_cols <- c("temp_jan", "precip_jan", "wind_jan")

# This will throw an error if even ONE of these columns is missing
weather_df %>% 
  select(all_of(target_cols))

# This is the "safe" version. It grabs whatever it finds and ignores the rest.
weather_df %>% 
  select(any_of(target_cols))

I almost always prefer any_of() when writing production code. It prevents your entire pipeline from crashing just because a data provider decided to rename wind_jan to wind_speed_jan in this month's export.

Can I select columns based on their data type?

Absolutely. This is a lifesaver when you need to perform an operation—like scaling or rounding—on every numeric column without knowing their names. You use the where() helper. It basically lets you pass a predicate function (a function that returns TRUE or FALSE) to filter the columns.

# Grab only the numeric columns for a correlation matrix
weather_df %>% 
  select(where(is.numeric))

# Or, if you want to find all character columns that might need cleaning
weather_df %>% 
  select(where(is.character))

I've found this incredibly useful when combined with across() in a mutate() call, but for just selecting, where() is the way to go.

Is matches() just a fancy way to do regex?

Pretty much. While starts_with() is great for simple stuff, matches() gives you the full power of regular expressions. If you have a complex naming scheme—like columns that start with a letter, followed by an underscore, and ending in a four-digit year—the basic helpers won't cut it.

# Select columns that match a pattern: word, underscore, then 4 digits
# Example: "temp_2021", "precip_2022"
weather_df %>% 
  select(matches("^[a-z]+_\\d{4}$"))

Fair warning: regex can get ugly fast. If you find yourself writing a 50-character regex string just to select three columns, stop and ask if you can just rename your data first. It'll make your code much easier for your future self to read.




📋 Practical Task

Cleaning the Global Sensor Dataset

You have been handed a messy dataframe called sensor_data. It contains the following columns: sensor_id, location_city, location_country, reading_temp_C, reading_humidity, reading_pressure, last_updated_date, and status_code.

Write a code snippet using dplyr::select() and tidyselect helpers to create a new dataframe called numeric_readings that meets these three criteria:

  • It includes the sensor_id column.
  • It includes all columns that start with the word reading.
  • It excludes any columns that are not numeric (aside from sensor_id).

Hint: Think about whether you should use starts_with() first or where(is.numeric) to ensure you don't accidentally keep non-numeric columns that might happen to start with "reading".

Rating
0 0

There are no comments for now.

to be the first to leave a comment.