dplyr: filter, select, and arrange
Prerequisites: Tibbles, Scope and anonymous functions
dplyr is the tidyverse package for transforming data. Each of its
functions — called verbs — does one job, takes a data frame as the
first argument, and returns a new data frame. Chained together with the
pipe |>, they read like a recipe.
library(dplyr, warn.conflicts = FALSE)
warn.conflicts = FALSE hides the message about dplyr functions
(such as filter) replacing base R functions with the same name. You'll
see that message the first time — it's informational, not an error.
We'll use this small dataset:
library(dplyr, warn.conflicts = FALSE)
staff <- tibble(
name = c("Ada", "Linus", "Grace", "Alan", "Margaret"),
team = c("Data", "Infra", "Data", "Research", "Infra"),
salary = c(72000, 65000, 91000, 58000, 83000),
years = c(5, 3, 12, 2, 8)
)
staff |> filter(team == "Data")
# A tibble: 2 × 4
name team salary years
<chr> <chr> <dbl> <dbl>
1 Ada Data 72000 5
2 Grace Data 91000 12
filter — keep rows
Inside dplyr verbs you refer to columns by bare names — no
staff$ prefix. Conditions separated by commas must all be true:
library(dplyr, warn.conflicts = FALSE)
staff <- tibble(
name = c("Ada", "Linus", "Grace", "Alan", "Margaret"),
team = c("Data", "Infra", "Data", "Research", "Infra"),
salary = c(72000, 65000, 91000, 58000, 83000),
years = c(5, 3, 12, 2, 8)
)
staff |> filter(salary > 60000, years >= 5)
staff |> filter(team %in% c("Infra", "Research"))
# A tibble: 3 × 4
name team salary years
<chr> <chr> <dbl> <dbl>
1 Ada Data 72000 5
2 Grace Data 91000 12
3 Margaret Infra 83000 8
# A tibble: 3 × 4
name team salary years
<chr> <chr> <dbl> <dbl>
1 Linus Infra 65000 3
2 Alan Research 58000 2
3 Margaret Infra 83000 8
select — keep columns
library(dplyr, warn.conflicts = FALSE)
staff <- tibble(
name = c("Ada", "Linus"),
team = c("Data", "Infra"),
salary = c(72000, 65000),
years = c(5, 3)
)
staff |> select(name, salary)
staff |> select(-years)
# A tibble: 2 × 2
name salary
<chr> <dbl>
1 Ada 72000
2 Linus 65000
# A tibble: 2 × 3
name team salary
<chr> <chr> <dbl>
1 Ada Data 72000
2 Linus Infra 65000
-years drops a column. Helpers such as starts_with("sales_"),
ends_with("_id"), and where(is.numeric) select groups of columns.
arrange — sort rows
library(dplyr, warn.conflicts = FALSE)
staff <- tibble(
name = c("Ada", "Linus", "Grace", "Alan", "Margaret"),
team = c("Data", "Infra", "Data", "Research", "Infra"),
salary = c(72000, 65000, 91000, 58000, 83000)
)
staff |> arrange(desc(salary)) |> head(3)
staff |> arrange(team, name)
# A tibble: 3 × 3
name team salary
<chr> <chr> <dbl>
1 Grace Data 91000
2 Margaret Infra 83000
3 Ada Data 72000
# A tibble: 5 × 3
name team salary
<chr> <chr> <dbl>
1 Ada Data 72000
2 Grace Data 91000
3 Linus Infra 65000
4 Margaret Infra 83000
5 Alan Research 58000
desc() sorts from largest to smallest; several columns sort by the
first, then the next.
Common mistakes
- Writing
filter(team = "Data")— one=is an argument name, not a comparison. dplyr's error message suggests==. - Forgetting to save the result. Verbs return a new data frame; write
data_team <- staff |> filter(...)to keep it.