group_by多分组致n()统计与geom_col图表数值差异的原因及疑问
我是R新手,正在处理Divvy Bike Share数据,数据子集如下:
我希望可视化一周内的总骑行次数,编写了两段仅group_by参数不同的代码:p1按member_casual、day_of_week分组,p2额外加入month分组,结果两张geom_col图表的y轴数值差异明显。
代码与结果
p1代码与图表
p1 <- df %>% group_by(member_casual, day_of_week) %>% summarize(total_rides = n()) %>% ggplot(aes(x = day_of_week, y = total_rides, fill = member_casual)) + geom_col(position = "dodge") + labs(title = "Total Rides by Days in a Week", subtitle = "Casual Customers vs. Members", y = "ride times count (in thousands)") + theme(axis.title.x = element_blank()) + scale_fill_discrete(name = "") + scale_y_continuous(labels = label_number(scale = 1e-3, suffix = "k")) p1

p2代码与图表
p2 <- df %>% group_by(member_casual, day_of_week, month) %>% summarize(total_rides = n()) %>% ggplot(aes(x = day_of_week, y = total_rides, fill = member_casual)) + geom_col(position = "dodge") + labs(title = "Total Rides by Days in a Week", subtitle = "Casual Customers vs. Members", y = "ride times count (in thousands)") + theme(axis.title.x = element_blank()) + scale_fill_discrete(name = "") + scale_y_continuous(labels = label_number(scale = 1e-3, suffix = "k")) p2

分组统计结果
p1对应的统计结果
df %>% group_by(member_casual, day_of_week) %>% summarize(total_rides = n())

p2对应的统计结果
df %>% group_by(member_casual, day_of_week, month) %>% summarize(total_rides = n())

疑问
我理解增加分组维度会让数据更细分,且细分后的总和等于p1的数值,但p2图表显示的并非总和,因此有两个疑问:
- p1与p2数值差异的原因及如何避免此类错误?
- p2中的数值来源是什么?
1. 差异原因与避免方法
p1是按member_casual和day_of_week做的全局分组统计,每个(member_casual, day_of_week)组合对应的total_rides是该组合在整个数据集里的总骑行次数;而p2加入month分组后,summarize得到的是每个月内(member_casual, day_of_week)组合的骑行次数。
但你用geom_col(position = "dodge")绘制p2时,ggplot没有区分月份维度,会把同一day_of_week、同一member_casual下的多个月份数据直接重叠覆盖,最终图表显示的是该组合下某一个月份的骑行次数(通常是数据框里最后出现的那个月份的数值),而非各月总和,这就是数值差异的核心原因。
避免方法:
- 若想展示每月的周度骑行数据,给p2添加分面:
+ facet_wrap(~month),每个月份的图表单独展示; - 若想把月份的数值叠加,将
position = "dodge"改为position = "stack",或者先按member_casual和day_of_week重新汇总(把各月数值相加); - 明确可视化目标:是看分月的周度数据,还是整体的周度数据,再匹配对应的分组和可视化方式。
2. p2中的数值来源
p2图表里的数值,是分组统计后的数据框中,同一day_of_week、同一member_casual下的某一条记录的数值。因为你的数据框里每个(member_casual, day_of_week)对应多个month的记录,ggplot绘制时未区分月份,会把这些记录的柱子放在同一位置,最终显示的是最后一条(或视觉最上层)的那个月份的骑行次数。比如你的tibble 2中,每个(member_casual, day_of_week)下有多个月份的total_rides,图表里的数值就是其中某一个月份的数值,而非总和。
内容的提问来源于stack exchange,提问作者Abooboo

