Search code examples
rggplot2dplyrgeom-bar

r/ggplot: compute bar plot share within group


I am using ggplot2 to make a bar plot that is grouped by one variable and reported in shares.

I would like the percentages to instead be a percentage of the grouping variable rather than a percentage of the whole data set.

For example,

library(ggplot2)
library(tidyverse)

ggplot(mtcars, aes(x = as.factor(cyl), 
               y = (..count..) / sum(..count..),
               fill = as.factor(gear))) + 
geom_bar(position = position_dodge(preserve = "single")) + 
geom_text(aes(label = scales::percent((..count..)/sum(..count..)),
        y= ((..count..)/sum(..count..))), stat="count") + 
theme(legend.position = "none")

Produces this output:

enter image description here

I'd like the percentages (and bar heights) to reflect the "within cyl" proportion rather than share across the entire sample. Is this possible? Would this involve a stat argument?

As an aside, if its possible to similarly position the geom_text call over the relevant bars that would be ideal. Any guidance would be appreciated.


Solution

  • Here is one way :

    library(dplyr)
    library(ggplot2)
    
    mtcars %>%
      count(cyl, gear) %>%
      group_by(cyl) %>%
      mutate(prop = prop.table(n) * 100) %>%
      ggplot() + aes(cyl, prop, fill = factor(gear), 
                     label = paste0(round(prop, 2), '%')) + 
      geom_col(position = "dodge") + 
      geom_text(position = position_dodge(width = 2), vjust = -0.5, hjust = 0.5)
    

    enter image description here