rguides

rename() / relocate()

rename(.data, ...)
relocate(.data, ..., .before = NULL, .after = NULL)

The rename() function changes column names without changing their position, while relocate() reorders columns without changing their names. Both are part of dplyr and always return a new tibble.

Syntax

rename(.data, ...)

relocate(.data, ..., .before = NULL, .after = NULL)

Parameters

ParameterTypeDefaultDescription
.datatibble / data.frame,Input data frame or tibble
...name-value pairs,For rename(): new_name = old_name. For relocate(): columns to move
.beforecolumn positionNULLMove selected columns before this column
.aftercolumn positionNULLMove selected columns after this column

Examples

Basic renaming

The core pattern is new_name = old_name, which changes the column label while preserving all other columns and their order. This is the most common use case — fixing a column name to match a naming convention or making it more descriptive:

library(dplyr)

df <- data.frame(
  id = 1:3,
  name = c("Alice", "Bob", "Carol"),
  score = c(85, 92, 78)
)

# Rename 'score' to 'total_score'
rename(df, total_score = score)
#   id  name total_score
# 1  1  Alice          85
# 2  2    Bob          92
# 3  3  Carol          78

Multiple renames

You can rename any number of columns in a single rename() call by listing multiple new = old pairs separated by commas. Each rename is applied independently, so the order of the pairs does not matter — they all happen at once:

df <- data.frame(x = 1:3, y = 4:6, z = 7:9)

rename(df, a = x, b = y, c = z)
#   a b c
# 1 1 4 7
# 2 2 5 8
# 3 3 6 9

Using relocate()

While rename() changes column names, relocate() changes column positions without altering names or values. You can move one or more columns to the front, or use .after to place them immediately after a specific column. The relocation respects all tidy-select semantics:

df <- data.frame(
  id = 1:3,
  name = c("Alice", "Bob", "Carol"),
  score = c(85, 92, 78)
)

# Move 'score' to the first position
relocate(df, score)
#   score  id  name
# 1    85  1  Alice
# 2    92  2    Bob
# 3    78  3  Carol

# Move 'name' after 'id'
relocate(df, name, .after = id)
#   id  name score
# 1  1 Alice    85
# 2  2   Bob    92
# 3 3 Carol    78

Combining rename and relocate

You can chain rename() and relocate() in a pipeline to both rename a column and reposition it. The pipe operator passes the result of each step to the next, so the column has its new name by the time relocate() references it:

df <- data.frame(
  id = 1:3,
  name = c("Alice", "Bob", "Carol"),
  score = c(85, 92, 78)
)

df %>%
  rename(total_score = score) %>%
  relocate(name, .before = id)
#    name id total_score
# 1 Alice  1          85
# 2   Bob  2          92
# 3 Carol  3          78

Common patterns

Rename with select syntax

rename_with() applies a function to column names, which is the programmatic alternative to listing pairs by hand. Pass any function that accepts a character vector and returns one — tolower(), toupper(), janitor::make_clean_names(), or a custom lambda — and every column name is transformed at once:

df <- data.frame(
  X1 = 1:3,
  X2 = 4:6,
  Y1 = 7:9
)

# Convert column names to lowercase
rename_with(df, tolower)
#   x1 x2 y1
# 1  1  4  7
# 2  2  5  8
# 3  3  6  9

# Rename using a function on column names
rename_with(df, ~ paste0(.x, "_new"))
#   X1_new X2_new Y1_new
# 1      1      4      7
# 2      2      5      8
# 3      3      6      9

Using .before and .after with multiple columns

When you need to move several columns at once to a specific location, combine relocate() with tidy-select helpers like starts_with() or use the .before and .after arguments to position the moved group relative to another column. All moved columns remain adjacent and in their original relative order:

df <- data.frame(
  a = 1:3, b = 2:4, c = 3:5, d = 4:6
)

# Move columns 'b' and 'c' to the front
relocate(df, b:c, .before = a)
#   b c a d
# 1 2 3 1 4
# 2 3 4 2 5
# 3 4 5 3 6

dplyr::rename() in practice

rename() renames columns: rename(df, new_name = old_name). Multiple renames can be done in one call: rename(df, id = user_id, date = created_at). Unlike select(), rename() keeps all columns, only the specified columns are renamed.

rename_with() applies a function to column names, enabling bulk renaming. rename_with(df, tolower) lowercases all column names. rename_with(df, ~ gsub("\.", "_", .), everything()) converts dots to the _ character. The second argument specifies which columns to apply the function to, it accepts the same selection helpers as select().

A common pattern after joining data frames: rename_with(df, ~ paste0(.x, "_source"), ends_with("_id")) adds a suffix to all columns ending in _id. This disambiguates column names that might otherwise clash after a join.

Base R equivalent: names(df)[names(df) == "old_name"] <- "new_name". The base approach is more error-prone with multiple renames: you must index correctly, and an off-by-one error silently renames the wrong column. rename() uses name-based matching, which is safer and more readable.

rename() takes new_name = old_name pairs. For programmatic renaming based on a named vector of c(new = old) pairs, use rename(!!!rename_vec) or the any_of() / all_of() helpers inside rename_with(). rename_with(.fn, .cols) applies a transformation function like tolower or snakecase::to_snake_case to selected column names, making bulk renaming concise.

rename() vs rename_with()

rename() renames specific columns with explicitly stated old and new names. rename_with() applies a function to the column names, transforming all selected names according to a rule. rename_with(df, tolower) converts all column names to lowercase. rename_with(df, ~str_replace_all(., " ", "_")) replaces spaces with hyphens across all column names.

Column names with special characters, spaces, parentheses, dashes, require backtick quoting in dplyr expressions. rename(df, new_name = "old name with spaces") quotes the old name as a string. After renaming to names without special characters, subsequent code does not require quoting. Cleaning column names early in a data pipeline prevents quoting issues throughout the rest of the analysis.

See also

  • dplyr::select()
  • dplyr::mutate()
  • dplyr::arrange() rename_with(df, toupper) applies toupper() to all column names, a common normalization step when receiving data with inconsistent casing.rename_with(df, ~ gsub("\.", "_", .x)) replaces dots with underscores in all column names — a common cleaning step after reading SPSS or SAS data. setNames(df, new_names_vec) renames all columns at once using a character vector. Unlike rename(), setNames() requires specifying all names, not just the ones to change. For renaming based on a lookup table: rename(df, !!!setNames(old_names, new_names)) where setNames creates a named vector of c(new = old) pairs.