dplyr::mutate()

mutate(.data, ..., .by = NULL, .keep = c("all", "used", "unused", "none"), .before = NULL, .after = NULL)
Returns: tibble · Updated March 13, 2026 · Tidyverse
dplyr data-transformation tidyverse

mutate() is a core dplyr verb that adds new columns or modifies existing ones. It computes values column-wise using vectorised operations, meaning the expression is applied to each row independently.

Syntax

mutate(.data, ..., .by = NULL, .keep = c("all", "used", "unused", "none"), .before = NULL, .after = NULL)

Parameters

ParameterTypeDefaultDescription
.datatibble / data.frameInput data frame or tibble
...name-value pairsNew column definitions using tidy select syntax
.bytidy-selectNULLOptional grouping column(s) for scoped operations
.keepstring”all”Which columns to keep: “all”, “used”, “unused”, “none”
.beforetidy-selectNULLPosition for new columns (column name or index)
.aftertidy-selectNULLPosition for new columns (column name or index)

Examples

Basic usage

Create a new column from existing columns:

library(dplyr)

df <- tibble(
  x = 1:5,
  y = c(2, 4, 6, 8, 10)
)

mutate(df, z = x + y)

Output:

# A tibble: 5 × 3
      x     y     z
  <int> <dbl> <dbl>
1     1     2     3
2     2     4     6
3     3     6     9
4     4     8    12
5     5    10    15

Multiple new columns

Create multiple columns in one call:

df <- tibble(
  name = c("Alice", "Bob", "Charlie"),
  age = c(25, 30, 35)
)

mutate(df,
  age_next_year = age + 1,
  name_upper = toupper(name)
)

Output:

# A tibble: 3 × 4
  name    age age_next_year name_upper
  <chr> <dbl>         <dbl> <chr>     
1 Alice    25            26 ALICE     
2 Bob      30            31 BOB       
3 Charlie 35            36 CHARLIE   

Using .by for grouped operations

Create columns within groups:

df <- tibble(
  group = c("A", "A", "B", "B"),
  value = c(10, 20, 30, 40)
)

mutate(df, 
  group_mean = mean(value), 
  .by = group
)

Output:

# A tibble: 4 × 3
  group value group_mean
  <chr> <dbl>      <dbl>
1 A        10         15
2 A        20         15
3 B        30         35
4 B        40         35

Using .keep to control output

# Keep only the new columns (and grouping cols if using .by)
mutate(df, z = x + y, .keep = "used")

Common Patterns

Conditional transformations:

mutate(df, 
  category = case_when(
    score >= 90 ~ "A",
    score >= 80 ~ "B",
    TRUE ~ "C"
  )
)

Cumulative calculations:

mutate(df, cum_sum = cumsum(value))

Ranking within groups:

mutate(df, 
  rank = row_number(value),
  .by = group
)

See Also