【问题标题】:Adding percentages for the whole group in a stacked ggplot2 bar chart在堆叠的 ggplot2 条形图中为整个组添加百分比
【发布时间】:2017-08-04 08:41:57
【问题描述】:

我正在尝试通过geom_text() 在堆叠的 ggplot2 条形图中添加组百分比,计数在 y 轴上。我已经在这里看到并阅读了this question,但我认为它没有为我提供解决方案。

这是一个可重现的例子:

library(ggplot2)
library(scales)

df <- data.frame(Var1 = rep(c("A", "B", "C"), each = 3),
                 Var2 = rep(c("Gr1", "Gr2", "Gr3"), 3),
                 Freq = c(10, 15, 5, 5, 4, 3, 2, 10, 15))

ggplot(df) + aes(x = Var2, y = Freq, fill = Var1) +
  geom_bar(stat = "identity") +
  geom_text(aes(y = ..count.., label = scales::percent(..count../sum(..count..))),
            stat = "count")

这是结果:

只是为了确保你明白我想要什么:我希望每个组 Gr1、Gr2、Gr3 在每个条形上方的百分比,总和为 100%。

基本上,这些是我这样做时得到的值:

prop.table(tapply(df$Freq, df$Var2, sum))

谢谢!

【问题讨论】:

    标签: r ggplot2 bar-chart


    【解决方案1】:

    我建议创建预先计算好的data.frame。我会用dplyr 来做,但你可以使用任何你喜欢的东西:

    library('dplyr')
    
    df2 <- df %>% 
      arrange(Var2, desc(Var1)) %>% # Rearranging in stacking order      
      group_by(Var2) %>% # For each Gr in Var2 
      mutate(Freq2 = cumsum(Freq), # Calculating position of stacked Freq
             prop = 100*Freq/sum(Freq)) # Calculating proportion of Freq
    
    df2
    
    # A tibble: 9 x 5
    # Groups:   Var2 [3]
       Var1  Var2  Freq Freq2     prop
      <chr> <chr> <dbl> <dbl>    <dbl>
    1     C   Gr1     2     2 11.76471
    2     B   Gr1     5     7 29.41176
    3     A   Gr1    10    17 58.82353
    4     C   Gr2    10    10 34.48276
    5     B   Gr2     4    14 13.79310
    6     A   Gr2    15    29 51.72414
    7     C   Gr3    15    15 65.21739
    8     B   Gr3     3    18 13.04348
    9     A   Gr3     5    23 21.73913
    

    由此产生的情节:

    ggplot(data = df2,
           aes(x = Var2, y = Freq,
               fill = Var1)) +
      geom_bar(stat = "identity") +
      geom_text(aes(y = Freq2 + 1,
                    label = sprintf('%.2f%%', prop)))
    

    编辑:

    好吧,我有点误会你了。但我将使用相同的方法 - 根据我的经验,最好将大部分计算排除在 ggplot 之外,这样会更容易预测。

    df %>% 
      mutate(tot = sum(Freq)) %>% 
      group_by(Var2) %>% # For each Gr in Var2 
      summarise(Freq = sum(Freq)) %>% 
      mutate(Prop = 100*Freq/sum(Freq))
    
    ggplot(data = df,
           aes(x = Var2, y = Freq)) +
      geom_bar(stat = "identity",
               aes(fill = Var1)) +
      geom_text(data = df2,
                aes(y = Freq + 1,
                    label = sprintf('%.2f%%', Prop)))
    

    新剧情:

    【讨论】:

    • 非常感谢安德烈!我确实试过了。但是,问题是我不希望栏的每个部分的百分比(我在问题中的表述可能具有误导性,我对其进行了轻微编辑)。我真正想要的是每个条上方的一个百分比,代表每个 Gr (Var2) 相对于所有数据的百分比。你也可以帮忙吗?
    • @swolf 相应地编辑了我的答案。
    猜你喜欢
    • 1970-01-01
    • 2018-06-04
    • 1970-01-01
    • 2020-10-12
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    相关资源
    最近更新 更多