分组汇总与 group_by()
按组聚合数据,并计算各组统计量
分组汇总与 group_by() 是 CoddyKit 上的免费 R Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。
为什么要对数据分组?
对数据分组是数据分析中最强大的操作之一。您不再对整个数据集计算统计量,而是在每个组内分别计算。dplyr 包通过先使用 group_by()、再使用 summarize(),让这一过程变得直观。
library(dplyr)
# Sample sales data
sales <- data.frame(
region = c('North','North','South','South','East'),
revenue = c(120, 95, 200, 175, 88),
units = c(10, 8, 15, 12, 7)
)
print(sales)group_by() 基础
group_by(col) 会标记数据框,使后续操作按组执行。它不会改变数据本身,只会添加分组元数据。您可以按一列或多列进行分组。
library(dplyr)
sales <- data.frame(
region = c('North','North','South','South','East'),
revenue = c(120, 95, 200, 175, 88),
units = c(10, 8, 15, 12, 7)
)
# Group by region
grouped <- sales %>% group_by(region)
print(grouped)
print(group_keys(grouped))group_by() 后的 summarize()
summarize()(或 summarise())会将每个组汇总为一行。您需要指定新的列名以及要应用的汇总函数。常用函数包括:n()、mean()、sum()、min() 和 max()。
library(dplyr)
sales <- data.frame(
region = c('North','North','South','South','East'),
revenue = c(120, 95, 200, 175, 88),
units = c(10, 8, 15, 12, 7)
)
sales %>%
group_by(region) %>%
summarize(
n = n(),
mean_revenue = mean(revenue),
total_units = sum(units)
)使用 n() 计数
summarize() 中的 n() 返回每个组的行数。它不需要参数。若要统计符合条件的行数,请使用 sum(condition)。n_distinct(col) 用于统计唯一值的数量。
library(dplyr)
employees <- data.frame(
dept = c('HR','HR','Eng','Eng','Eng','Sales'),
salary = c(55000, 60000, 95000, 105000, 90000, 70000),
senior = c(FALSE, TRUE, TRUE, TRUE, FALSE, FALSE)
)
employees %>%
group_by(dept) %>%
summarize(
count = n(),
senior_count = sum(senior),
avg_salary = mean(salary)
)按多列分组
您可以向 group_by() 传入多列。分组依据是数据中出现的各列值的所有组合。这对于交叉制表和分层汇总非常有用。
library(dplyr)
orders <- data.frame(
region = c('North','North','South','South','North','South'),
product = c('A','B','A','B','A','A'),
sales = c(100, 200, 150, 250, 120, 180)
)
orders %>%
group_by(region, product) %>%
summarize(
total_sales = sum(sales),
orders = n(),
.groups = 'drop'
).groups 参数
执行 summarize() 后,结果仍会按除最后一个分组变量之外的所有变量分组。.groups 参数用于控制这一行为:
'drop_last'——默认值,删除最后一个分组层级'drop'——删除所有分组'keep'——保留所有分组
library(dplyr)
df <- data.frame(
year = c(2022,2022,2023,2023),
quarter = c('Q1','Q2','Q1','Q2'),
revenue = c(100, 120, 130, 150)
)
# .groups = 'drop' ensures ungrouped result
result <- df %>%
group_by(year, quarter) %>%
summarize(total = sum(revenue), .groups = 'drop')
print(result)
print(is.grouped_df(result)) # FALSE显式使用 ungroup()
您可以随时调用 ungroup(),从数据框中删除分组元数据。当您希望后续操作针对完整数据执行,而不是按组执行时,这一点非常重要。
library(dplyr)
df <- data.frame(
dept = c('HR','HR','Eng','Eng'),
salary = c(55000, 60000, 95000, 105000)
)
# Without ungroup: rank is within group
df %>%
group_by(dept) %>%
mutate(rank_in_dept = rank(salary)) %>%
ungroup() %>%
mutate(rank_overall = rank(salary))group_keys() 和 n_groups()
group_keys() 返回一个数据框,其中显示各个唯一的分组组合。n_groups() 告诉您共有多少个组。在执行分组操作前,这些函数对于了解分组情况非常有用。
library(dplyr)
df <- data.frame(
country = c('US','US','UK','UK','DE'),
category = c('A','B','A','A','B'),
value = c(10, 20, 15, 25, 30)
)
grouped <- df %>% group_by(country, category)
cat('Number of groups:', n_groups(grouped), '\n')
print(group_keys(grouped))汇总多个统计量
您可以在一次 summarize() 调用中计算多个汇总统计量,将计数、均值、中位数、标准差、最小值、最大值和自定义计算一次性组合起来。
library(dplyr)
scores <- data.frame(
class = c('A','A','A','B','B','B','C','C'),
score = c(85, 90, 78, 92, 88, 95, 70, 75)
)
scores %>%
group_by(class) %>%
summarize(
n = n(),
mean_score = round(mean(score), 1),
median_score = median(score),
sd_score = round(sd(score), 2),
min_score = min(score),
max_score = max(score)
)按组感知的 mutate()
在 group_by() 后使用 mutate(),会在每个组内计算值,但保留所有行(不同于 summarize())。这非常适合计算需要附加到每一行的组级指标。
library(dplyr)
sales <- data.frame(
region = c('East','East','West','West','West'),
rep = c('Alice','Bob','Carol','Dave','Eve'),
revenue = c(150, 200, 120, 180, 160)
)
sales %>%
group_by(region) %>%
mutate(
region_total = sum(revenue),
pct_of_region = round(100 * revenue / sum(revenue), 1)
) %>%
ungroup()在组内筛选
在 group_by() 后使用 filter(),会根据组级条件筛选行。例如,只保留每个区域表现最佳的记录,或保留数值超过组均值的行。
library(dplyr)
sales <- data.frame(
region = c('East','East','West','West','North','North'),
rep = c('Alice','Bob','Carol','Dave','Eve','Frank'),
revenue = c(150, 200, 120, 180, 95, 130)
)
# Keep the top rep per region
sales %>%
group_by(region) %>%
filter(revenue == max(revenue)) %>%
ungroup()快速检查
summarize() 中的 .groups = 'drop' 参数有什么作用?
回顾:分组汇总
分组汇总的要点:
group_by(col)添加分组——数据不变,但操作会按组执行summarize()将每个组汇总为一行——可使用n()、mean()、sum()等函数.groups = 'drop'确保结果取消分组ungroup()可随时删除分组group_keys()查看分组层级;n_groups()统计分组数量mutate()+group_by()添加组级列,同时不合并各行
library(dplyr)
# Full pipeline example
data.frame(
dept = c('Eng','Eng','HR','HR','Sales'),
salary = c(95000, 110000, 60000, 65000, 75000)
) %>%
group_by(dept) %>%
summarize(
headcount = n(),
avg_salary = mean(salary),
.groups = 'drop'
) %>%
arrange(desc(avg_salary))用 AI 导师学习 R — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 43
- 课程
- 159
常见问题解答
「分组汇总与 group_by()」课时是免费的吗?
是的 — 「分组汇总与 group_by()」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。
「分组汇总与 group_by()」这节课中我会学到什么?
按组聚合数据,并计算各组统计量 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 R Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「分组汇总与 group_by()」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 R Academy 课中编写并运行代码吗?
能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 分组汇总与 group_by()
- 窗口函数:lag、lead、cumsum
- dplyr 中的多表连接
- 整洁求值:{{ }} 与 .data