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

为何相同ggplot2代码生成的图表百分比标签不一致?

问题原因与解决方案

问题原因

这个不一致问题和dplyr版本的行为变化直接相关,而非R版本本身:

  • 旧版dplyr(1.0.0之前)执行summarise()后会保留所有分组变量;
  • 新版dplyr(1.0.0及以后)默认启用drop_last = TRUE,执行summarise()后会自动移除最后一个分组变量。

你的原代码依赖了dplyr的默认分组行为,没有明确指定百分比计算的统计范围:

  • 若之前环境的dplyr版本较旧,分组保留规则导致sum(count)统计的是单个月份的总骑行数,因此百分比反映会员/非会员在当月的占比;
  • 升级后dplyr的默认行为改变,sum(count)的统计范围变为单个会员类型的总骑行数,因此百分比变成各月份在该类型中的占比。

解决方案

要生成「会员/非会员在当月的占比」标签,需明确控制分组逻辑,确保sum(count)的统计范围是单个月份的总骑行数:

修正后的原代码

Divvy22_clean %>%
  group_by(start_mth, member_casual) %>%
  dplyr::summarise(count = n(), .groups = "drop_last") %>%  # 明确保留start_mth分组
  mutate(percent = count/sum(count)*100) %>%  # 按月份计算占比
  ggplot(aes(start_mth, count, fill = member_casual)) + 
  geom_col(position = "stack") + 
  geom_text(aes(label = paste0(round(percent), "%")), 
            position = position_stack(vjust = 0.5), size = 3, color = "white") +
  scale_y_continuous(limits = c(0, 900000), expand = c(0, 0)) + 
  labs(x = "Months, 2022", y = "Total Rentals", 
       title = "Ride Distribution by Month and Membership Type")+
  facet_wrap(~member_casual)

修正后的模拟代码

set.seed(123) 

start_mth <- rep(c("Jan", "Feb", "Mar"), each = 2)
member_casual <- rep(c("member", "casual"), times = 3)
count <- round(runif(6, 0, 900000))
Divvy_example <- data.frame(start_mth, member_casual, count)

# 按月份分组计算各类型占比
Divvy_example <- Divvy_example %>%
  group_by(start_mth) %>%
  mutate(percent = count/sum(count) * 100) %>%
  ungroup()

# 绘图
ggplot(Divvy_example, aes(start_mth, count, fill = member_casual)) + 
  geom_col(position = "stack") + 
  geom_text(aes(label = paste0(round(percent), "%")), 
            position = position_stack(vjust = 0.5), size = 3, color = "white") + 
  scale_y_continuous(limits = c(0, 900000), expand = c(0, 0)) + 
  labs(x = "Months, 2022", y = "Total Rentals", 
       title = "Ride Distribution by Month and Membership Type") +
  facet_wrap(~member_casual)

关键修改说明

  1. 使用.groups = "drop_last"明确指定summarise()后的分组保留规则,确保后续计算百分比时以start_mth为分组依据;
  2. 若不需要保留分组,也可直接在计算百分比时重新group_by(start_mth),确保sum(count)统计的是单个月份的总骑行数。

如果你的需求是「每个会员类型下,各月份骑行数占该类型总数的百分比」,只需将分组改为group_by(member_casual)即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:02:51