使用ggplot的geom_bar绘制按组和facet_wrap分组的百分比图

3
我希望在单个图表上绘制多个类别,每个类别的百分比加起来总共为100%。例如,如果我正在绘制男性与女性,每个分组(男性或女性)将总计100%。我正在使用以下代码,其中百分比似乎适用于两个图表上的所有组,即如果您将左侧和右侧图表上的所有条形图相加,则它们将总计100%,而不是左侧图上的黄色条形图总计100%,左侧图中的紫色条形图等。
我知道可以通过使用stat ='identity'实现此目的,但是否有一种方法在绘制之前无需整理数据框架就能在ggplot中实现?
library(ggplot2)  

tmp <- diamonds %>% filter(color %in% c("E","I")) %>% select(color, cut, clarity)

ggplot(data=tmp,
     aes(x=clarity,
         fill=cut)) + 
  geom_bar(aes(y = (..count..)/sum(..count..)), position="dodge") +
  scale_y_continuous(labels = scales::percent) + facet_wrap(vars(color))

enter image description here

1个回答

4

在ggplot2中计算百分比时,您需要像在将数据汇总后传递给ggplot之前一样对数据进行分组。在您的情况下,由ggplot2内部添加到数据中的PANEL列可用于分组:

使用after_stattapply可以实现如下:

library(ggplot2)  
library(dplyr)

tmp <- diamonds %>% filter(color %in% c("E","I")) %>% select(color, cut, clarity)

ggplot(data=tmp,
       aes(x=clarity,
           fill=cut)) + 
  geom_bar(aes(y = after_stat(count/tapply(count, PANEL, sum)[PANEL])), position="dodge") +
  scale_y_continuous(labels = scales::percent) + facet_wrap(vars(color))

或使用..符号:

ggplot(data=tmp,
       aes(x=clarity,
           fill=cut)) + 
  geom_bar(aes(y = ..count../tapply(..count.., ..PANEL.., sum)[..PANEL..]), position="dodge") +
  scale_y_continuous(labels = scales::percent) + facet_wrap(vars(color))

编辑 如果需要按多个变量分组,建议使用辅助函数。我将使用 dplyr 进行计算:

comp_pct <- function(count, PANEL, cut) {
  data.frame(count, PANEL, cut) %>% 
    group_by(PANEL, cut) %>% 
    mutate(pct = count / sum(count)) %>% 
    pull(pct)
}

ggplot(data=tmp,
       aes(x=clarity,
           fill=cut)) + 
  geom_bar(aes(y = after_stat(comp_pct(count, PANEL, fill))), position="dodge") +
  scale_y_continuous(labels = scales::percent) + facet_wrap(vars(color))


谢谢Stefan,离目标越来越近了。将左侧图表中的黄色条形图相加仍然会得到比左侧面板中的紫色条形图更大的数字。我希望它们都等于100%。除了面板之外,您还能否按切割分组? - pluke
嗨 pauke。当然可以按多个变量进行分组。请查看我的编辑。 - stefan
太棒了,这是一种相当不错的做法。 - pluke
1
@stefan 做得好,兄弟。大高五。 - Josh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接