You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

理解dplyr中summarise函数的.groups="drop"参数及异常排查

关于dplyr summarise中.groups="drop"的作用及分组缺失问题解答

为什么不加.groups="drop"会返回远超20行的结果?

在dplyr 1.0.0及之后的版本里,summarise()的默认.groups参数是"drop_last"——简单说就是执行完汇总后,会删掉分组变量列表里的最后一个,保留前面所有分组。

你的代码里用group_by(start_station_name, start_lat, start_lng)指定了三个分组变量,所以summarise()执行后,分组会变成start_station_name和start_lat,并没有完全取消分组。

这就导致后续的arrange(desc(count))和slice(1:20)都是按每个分组(也就是每个start_station_name + start_lat的组合)单独运行的:比如如果有10个不同的start_station_name + start_lat组合,每个组合里都会被取前20行,最终总行数自然会远超20。

而添加.groups="drop"后,summarise()会直接移除所有分组,把数据变回普通的未分组数据框。这时候arrange是全局排序,slice(1:20)就会从整个数据集中取排名前20的记录,完全符合你的需求。

为什么groups(summary)里看不到start_lng?

还是因为"drop_last"的默认行为:你最初的分组变量顺序是start_station_name → start_lat → start_lng,summarise()默认会去掉最后一个分组变量(也就是start_lng),只保留前面两个。所以调用groups(summary)时,只会显示剩下的分组变量。

用实际示例验证

我们构造一个模拟数据集来复现你的场景:

library(dplyr)

# 模拟出行数据:10个不同的站点组合,每个组合对应50条记录
trips_2023 <- tibble(
  member_casual = rep("member", 500),
  start_station_name = rep(paste0("Station ", LETTERS[1:10]), each=50),
  start_lat = rep(seq(40.71, 40.80, 0.01), each=50),
  start_lng = rep(seq(-74.00, -73.91, 0.01), each=50)
)

# 不加.groups="drop"的情况
summary_no_drop <- trips_2023 %>% 
  filter(member_casual == "member") %>%
  group_by(start_station_name, start_lat, start_lng) %>%
  summarise(count = n()) %>%
  arrange(desc(count)) %>%
  mutate(type = "start", member = "member") %>% 
  slice(1:20)

# 查看当前分组
groups(summary_no_drop)
# 输出:Groups: start_station_name, start_lat [10]

# 查看结果行数
nrow(summary_no_drop)
# 输出:10(每个分组里只有1条记录,slice(1:20)会取所有分组的记录)

# 添加.groups="drop"的情况
summary_with_drop <- trips_2023 %>% 
  filter(member_casual == "member") %>%
  group_by(start_station_name, start_lat, start_lng) %>%
  summarise(count = n(), .groups = "drop") %>%
  arrange(desc(count)) %>%
  mutate(type = "start", member = "member") %>% 
  slice(1:20)

# 查看当前分组
groups(summary_with_drop)
# 输出:NULL(无任何分组)

# 查看结果行数
nrow(summary_with_drop)
# 输出:10(全局排序后取前20,这里只有10条记录,所以全部保留;如果有30条,就会取前20)

总结

  • .groups="drop"的核心作用是在summarise后完全清除所有分组,让后续操作在整个数据集上执行,而非按分组拆分执行。
  • 默认的.groups="drop_last"会保留除最后一个之外的所有分组变量,这就是你看到分组缺失start_lng的直接原因。
  • 如果你不想用.groups="drop",也可以在summarise()之后加一行ungroup(),能达到完全一样的效果。

内容的提问来源于stack exchange,提问作者gorilla_ballz123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 17:43:24