dplyr pipelines are the most common way data is cleaned and summarised in modern R.
The native pipe |> (R 4.1+) passes the left side as the first argument of the call on the right: x |> f(y) is f(x, y). Pipelines read top to bottom instead of inside out. The magrittr pipe %>% predates it and still appears everywhere; for most code they're interchangeable.
dplyr provides one verb per operation, each taking a data frame first and returning a new one:
filter(df, cond)keeps rows;arrange(df, desc(x))sorts.select(df, a, b)picks columns (with helpers likestarts_with);renamerenames.mutate(df, new = expr)adds or changes columns.summarise(df, n = n(), avg = mean(x))reduces to one row.group_by(df, g)makes the nextsummariseormutatework per group. Use.by = gfor a one-off grouping.left_join,inner_joincombine tables by key columns.
Inside verbs you refer to columns by bare name (data masking), so filter(df, age > 30) needs no df$. Use .data$col to be explicit, and {{ arg }} when wrapping dplyr in your own functions.
The tidyverse also includes tidyr for reshaping (pivot_longer, pivot_wider) and readr for import; library(tidyverse) loads them together.
Example
library(dplyr, warn.conflicts = FALSE)
mtcars |>
filter(hp > 100) |>
mutate(kpl = round(mpg * 0.425, 1)) |>
group_by(cyl) |>
summarise(n = n(), avg_kpl = mean(kpl), .groups = "drop") |>
arrange(desc(avg_kpl)) |>
print()
#> # A tibble: 3 x 3
#> cyl n avg_kpl
#> <dbl> <int> <dbl>
#> 1 4 2 11
#> 2 6 7 8.4
#> 3 8 14 6.43
teams <- tibble(cyl = c(4, 8), label = c("small", "big"))
mtcars |> count(cyl) |> left_join(teams, by = "cyl") |> print()
#> cyl n label
#> 1 4 11 small
#> 2 6 7 <NA>
#> 3 8 14 bigRemember
x |> f(y)meansf(x, y)- Verbs: filter, select, mutate, summarise, arrange, joins
group_by(or.by) makes summaries per group- Columns are referenced by bare name inside verbs
Watch out for
- Forgetting that group_by stays attached to the result, so later mutates run per group unexpectedly.