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

如何使用ggplot绘制按分组百分比统计的直方图

实现分队列组内归一化的绘图方案

原有代码的问题

你使用的y = stat(density)无法达到预期效果:stat(density)返回的是全局核密度估计值,且直方图的密度计算逻辑不匹配你需要的「每个队列内各得分频数占比之和为1」的需求。

推荐实现方式

因为你的Depression得分是1-4的离散值,优先选择geom_col/geom_bar而非直方图实现,两种可行方案如下:

方案1:提前统计占比(逻辑清晰,易调试)

先按队列分组计算每个得分的占比,再绘图:

library(tidyverse)

# 示例数据
d <- structure(list(Cohort = c("Fall", "Spring", "Summer", "Fall", 
"Spring", "Summer", "Fall", "Spring", "Summer", "Fall", "Spring", 
"Summer", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", 
"Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Summer", "Fall", 
"Spring", "Summer", "Fall", "Spring", "Summer", "Fall", "Spring", 
"Summer", "Spring", "Spring", "Fall", "Fall", "Fall", "Fall", 
"Fall", "Fall"), Depression = c(1, 2, 2, 4, 2, 1, 1, 3, 2, 3, 
2, 4, 2, 2, 4, 2, 1, 1, 3, 1, 3, 2, 4, 3, 3, 2, 4, 2, 1, 1, 3, 
2, 3, 2, 4, 1, 4, 1, 1, 3, 4, 1, 1)), row.names = c(NA, -43L), class = c("tbl_df", 
"tbl", "data.frame"))

# 分组统计占比
d_stats <- d %>%
  count(Cohort, Depression) %>%
  group_by(Cohort) %>%
  mutate(pct = n / sum(n)) %>%
  ungroup()

# 绘图
ggplot(d_stats, aes(x = factor(Depression), y = pct, fill = Cohort)) +
  geom_col(position = position_dodge(0.9), width = 0.8) +
  scale_y_continuous(labels = scales::percent(), limits = c(0, NA)) +
  labs(x = "Depression得分", y = "队列内占比") +
  theme_minimal()

方案2:直接在ggplot层计算(无需预处理数据)

如果不想提前做数据汇总,可以通过after_stat实现实时分组计算:

ggplot(d, aes(x = factor(Depression), fill = Cohort)) +
  geom_bar(
    aes(y = after_stat(count / ave(count, group, FUN = sum))),
    position = position_dodge(0.9)
  ) +
  scale_y_continuous(labels = scales::percent(), limits = c(0, NA)) +
  labs(x = "Depression得分", y = "队列内占比") +
  theme_minimal()

两种方案都可以保证每个队列对应的4个柱子的占比之和为1,不受队列样本量差异的影响。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 03:45:02