R Academy · 课时

分组汇总与 group_by()

按组聚合数据,并计算各组统计量

第 1 / 4 课13 个步骤

分组汇总与 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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 分组汇总与 group_by()
  2. 窗口函数:lag、lead、cumsum
  3. dplyr 中的多表连接
  4. 整洁求值:{{ }} 与 .data
← 返回 R Academy