Crash Courses · Masters
Data Manipulation with dplyr
Transform, filter, group, and summarize data frames using dplyr's grammar of data manipulation — the most important R package for analysis.
18 min read+175 XP on completionCert: R Crash Course
Tap any word in the text below to start reading from there.
Data Manipulation with dplyr
Installing and Loading dplyr
install.packages("dplyr") # run once
library(dplyr) # load every sessionOr install the entire tidyverse at once: install.packages("tidyverse")
---
Sample Data
library(dplyr)
sales <- data.frame(
id = 1:10,
product = c("Laptop","Phone","Desk","Laptop","Monitor","Phone","Chair","Laptop","Monitor","Desk"),
category = c("Electronics","Electronics","Furniture","Electronics","Electronics",
"Electronics","Furniture","Electronics","Electronics","Furniture"),
price = c(1299,799,450,1199,599,849,299,1399,649,399),
qty = c(2,5,3,1,4,2,6,3,2,4),
region = c("North","South","North","East","West","South","North","East","West","South"),
stringsAsFactors = FALSE
)---
The Pipe Operator
# Without pipe (hard to read — inside-out):
arrange(select(filter(sales, category == "Electronics"), product, price), price)
# With pipe (left-to-right, readable):
sales %>%
filter(category == "Electronics") %>%
select(product, price) %>%
arrange(price)
# Native pipe (R 4.1+) — no package needed:
sales |>
filter(category == "Electronics") |>
select(product, price) |>
arrange(price)---
Core dplyr Verbs
filter() — keep rows matching conditions:
sales %>% filter(price > 800)
sales %>% filter(category == "Electronics", region == "North")
sales %>% filter(price >= 500 & price <= 1000)
sales %>% filter(product %in% c("Laptop", "Phone"))select() — choose columns:
sales %>% select(product, price, qty)
sales %>% select(-id) # exclude id
sales %>% select(starts_with("p")) # product, price
sales %>% select(where(is.numeric)) # numeric columns onlymutate() — add or modify columns:
sales %>%
mutate(
revenue = price * qty,
discount = if_else(price > 1000, price * 0.1, 0),
final_rev = revenue - discount,
category_upper = toupper(category)
)arrange() — sort rows:
sales %>% arrange(price) # ascending
sales %>% arrange(desc(price)) # descending
sales %>% arrange(category, desc(price)) # multi-key sortgroup_by() + summarise() — aggregation:
sales %>%
group_by(category) %>%
summarise(
total_revenue = sum(price * qty),
avg_price = mean(price),
n_products = n(),
.groups = "drop"
)
# category total_revenue avg_price n_products
# 1 Electronics 23291 882.4 7
# 2 Furniture 5346 382.7 3
# Multiple grouping variables
sales %>%
group_by(category, region) %>%
summarise(revenue = sum(price * qty), .groups = "drop") %>%
arrange(category, desc(revenue))---
Advanced Operations
# slice — select rows by position
sales %>% slice_max(price, n = 3) # top 3 most expensive
sales %>% slice_min(qty, n = 2) # 2 lowest quantity
# rename — rename columns
sales %>% rename(units = qty, item = product)
# count — frequency tables
sales %>% count(category)
sales %>% count(region, sort = TRUE)
# across — apply function to multiple columns
sales %>%
group_by(category) %>%
summarise(across(c(price, qty), list(mean = mean, sum = sum)))
# Joins
customers <- data.frame(
id = 1:5,
name = c("Alice", "Bob", "Carol", "David", "Emma")
)
# left_join — keep all rows from sales
left_join(sales, customers, by = "id")---
Complete Pipeline Example
top_performers <- sales %>%
mutate(revenue = price * qty) %>%
group_by(product) %>%
summarise(
total_revenue = sum(revenue),
units_sold = sum(qty),
avg_price = mean(price),
.groups = "drop"
) %>%
mutate(revenue_share = total_revenue / sum(total_revenue) * 100) %>%
arrange(desc(total_revenue)) %>%
slice_head(n = 5)
print(top_performers)Reading progress
0% read
In this module
dplyr
Pipe operator (%>% or |>)
group_by + summarise
mutate()
0%