ggplot按分组统计百分比实现分类数据可视化问题咨询
ggplot按分组维度计算单组内百分比的实现方法
原有代码的问题
原有代码输出全局占比而非组内占比,核心是三个问题:
dplyr::group_by()的分组规则不会自动传递给ggplot的统计计算逻辑,管道里加group_by(d)对后续ggplot的计数逻辑没有任何作用- 原来的
(..count..)/sum(..count..)写法是对全量数据的所有计数求和,计算基准是整个数据集,自然无法得到单组内的占比 - 代码里错误引用了不存在的数据集
DataT,且全局映射未指定分组维度(fill),进一步导致统计逻辑无法按组拆分
正确实现方法
方法1:绘图层直接计算(无需提前统计)
用ggplot2支持的after_stat()获取统计后的计数值,配合ave()按分组维度计算组内总和,直接得到组内占比:
library(tidyverse) library(scales) # 示例数据 c <- c("Impossible", "Easy", "Impossible", "Difficult", "Impossible", "Difficult", "Easy", "Easy", "Easy", "Difficult") d <- c("F", "F", "V", "V", "F", "F", "V", "F", "V", "F") e <- data.frame(c,d) # 绘图 plot_by_group <- e %>% ggplot(mapping = aes(x = c, fill = d)) + geom_bar( aes(y = after_stat(count / ave(count, fill, FUN = sum))), position = "dodge2" ) + scale_y_continuous(labels = percent, name = "组内占比") plot_by_group
关键逻辑说明:ave(count, fill, FUN = sum)会按照fill映射的d列分组,分别计算F、V两个组各自的总样本量,再用单个难度类别的计数除以对应组的总样本量,最终每个分组下的柱形占比累加为100%。
方法2:提前统计占比后绘图(逻辑更可控)
如果怕统计口径出错,可以先用dplyr提前算好每个组内的百分比,再用geom_col()绘图,中间结果可直接核对:
plot_precomputed <- e %>% # 交叉统计两个分类变量的频数 count(d, c) %>% # 按d分组计算组内占比 group_by(d) %>% mutate(pct = n / sum(n)) %>% ungroup() %>% # 传入统计好的结果绘图 ggplot(aes(x = c, y = pct, fill = d)) + geom_col(position = "dodge2") + scale_y_continuous(labels = percent, name = "组内占比") plot_precomputed
这个方法可以在绘图前直接输出统计的表格,确认每个d分组的pct列累加为1,避免统计逻辑错误。
内容的提问来源于stack exchange,提问作者C.L.
相关产品推荐
相关产品推荐

