dplyr::select()
select(.data, ...) select() is a dplyr verb that subsets columns from a data frame or tibble.
Syntax
select(.data, ...)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
.data | data.frame/tibble | , | A data frame or tibble to select from |
... | , | Column selections using names, positions, or helpers |
Examples
Basic column selection
The simplest form of select() takes one or more bare column names and returns a tibble containing only those columns, in the order you specify. Columns not listed are silently dropped from the output:
library(dplyr)
df <- tibble(
id = 1:5,
name = c("Alice", "Bob", "Charlie", "Diana", "Eve"),
age = c(25, 30, 35, 28, 32),
salary = c(50000, 60000, 55000, 65000, 58000)
)
# Select two columns
select(df, name, age)
Using column positions
You can reference columns by their numeric index instead of by name. Positive integers select from the leftmost position, which is convenient in ad-hoc interactive work where column indices are easily visible in the RStudio viewer pane or when you are exploring the structure of an unfamiliar dataset:
# Select first and third columns
select(df, 1, 3)
Selection helpers
Tidy-select helpers like starts_with(), ends_with(), contains(), and matches() let you select columns whose names match a pattern without knowing them ahead of time. These are particularly useful when column names follow a systematic naming convention across a wide data frame:
# Select columns that start with "s"
select(df, starts_with("s"))
# Select columns that contain "a"
select(df, contains("a"))
Renaming columns
You can rename columns while selecting them by using new_name = old_name, just like in rename(). This combines two operations — keeping a subset of columns and giving them cleaner names — into a single concise expression. The result is a tibble with only the renamed columns, in the order specified:
select(df, ID = id, Employee = name)
Using everything() helper
The everything() helper is a wildcard that selects all remaining columns not yet mentioned. Combined with specific columns listed first, it moves those columns to the front while preserving every other column in its original order. This is the cleanest way to bring an important column to the front without dropping any data:
select(df, salary, everything())
Negative selection
Prefix a column name with - to drop it while keeping everything else. You can also negate tidy-select helpers: -starts_with("temp_") removes every column whose name begins with temp_ without having to list them all individually. This is especially useful when cleaning up intermediate columns added during data processing:
select(df, -salary)
Common patterns
Pipeline with select()
select() is frequently the first step in a pipeline, narrowing the data to only the columns needed before applying more expensive operations like joins or grouped summaries. A typical pattern selects a few columns, filters rows by condition, and then displays the first few results:
df %>%
select(name, age) %>%
filter(age > 28) %>%
head(3)
Select numeric columns
The where() helper applies a predicate function to each column and keeps only the ones for which the predicate returns TRUE. where(is.numeric) is the standard pattern for pulling out all numeric columns from a data frame that mixes numeric and character data:
# Select all numeric columns
df %>% select(where(is.numeric))
Reorder columns
select() can rearrange columns in any order by listing them in the sequence you want. Unlike relocate(), this approach also filters to only the columns you name, so it is a combined reorder-and-subset operation rather than a pure reordering. List every column you want to keep in the new order to get a fully rearranged tibble:
select(df, name, age, salary, id)
dplyr::select() in practice
select() subsets columns from a data frame. Unlike base R’s df[, c("a","b")], it accepts bare column names without quotes, selection helpers, and negative selection with -. select(df, a, b) keeps columns a and b. select(df, -c) drops column c while keeping all others.
Selection helpers provide expressive column selection. starts_with("temp_") selects columns beginning with "temp_". ends_with("_id") selects columns ending with "_id". contains("date") selects columns containing "date" anywhere in the name. matches("^col_[0-9]+$") uses regex. num_range("Q", 1:4) selects Q1, Q2, Q3, Q4. where(is.numeric) selects all numeric columns.
select() also reorders columns: select(df, id, everything()) moves id to the first position while keeping all other columns. relocate() is cleaner for reordering, but select() with everything() is a common idiom.
rename() is preferred over select() when the goal is renaming, not subsetting, select() drops unmentioned columns unless everything() is included, which is easy to forget. rename_with() renames multiple columns using a function: rename_with(df, tolower) lowercases all column names.
select() returns a data frame with only the chosen columns. It accepts bare column names, positions, and tidy-select helpers: starts_with(), ends_with(), contains(), matches(), num_range(), everything(), last_col(), and where(). Negative selection with -col or !col drops columns. select(df, where(is.numeric)) keeps only numeric columns. Reordering columns is also done with select(), list columns in the desired order.
Negative selection and exclusion
Excluding columns with the minus or exclamation mark prefix is often more concise than listing what to keep when the exclusions are few. select(-id, -created_at) removes two columns and keeps everything else. Using !c(id, created_at) inside select() achieves the same result. For excluding a pattern of columns, all columns starting with “temp_”, select(-starts_with("temp_")) removes all matching columns without naming each.
Reordering columns without dropping any uses select() to list the desired columns first, followed by everything() to include the remaining columns in their original order. select(id, name, status, everything()) puts the three named columns first and then appends all other columns. This pattern restructures a data frame to put the most important columns on the left for easier visual inspection without losing any data.
See also
- dplyr::filter()
- dplyr::mutate()
- dplyr::arrange()
select(where(is.numeric))keeps only numeric columns;select(!where(is.character))drops character columns.select()is also a column reordering tool —select(df, id, name, everything())movesidandnamefirst and keeps all other columns.relocate(df, col, .before = other_col)or.after = other_colis a cleaner alternative for reordering.select()withwhere(is.numeric)andwhere(is.character)filters by column type. For dynamic column selection in functions, useselect(df, all_of(char_vec))for exact matching orany_of(char_vec)which silently ignores missing columns.