Search code examples
rggplot2bar-chartgeom-bargeom-text

How to get geom bar percentages to reflect within-group percentages rather than the overall percentage


I have a dataset in R that looks like this:

'f' is the dataset, column 'e' (character) is the group variable, column 'd' (factor) is the data

With the following code I get the graph below:

ggplot(subset(f,!is.na(d)),aes(x=d,y=(..count..)/sum(..count..),fill=forcats::fct_rev(e))) + 
 geom_bar(position="dodge") + 
 scale_y_continuous(labels = scales::percent) +
 theme(panel.grid.major.y = element_line(color="gray"),
    panel.background =element_blank(), axis.line=element_line("black"), axis.text.x=element_text(face="bold"), 
    legend.title=element_blank(), axis.title.y=element_blank(), axis.title.x=element_blank(),
    plot.title = element_text(hjust = 0.5)
 ) +
 scale_x_discrete(
   labels=c('$0', '$1 to $10K', 'Over $10K to $20K', 'Over $20K to $30K','Over $30K to $40K','Over $40K to $50K','Over $50K')
 ) +
 geom_text(aes(label = scales::percent(round((..count..)/sum(..count..),2)),y= ((..count..)/sum(..count..))), stat="count", position = position_dodge(width = .9),vjust = -1)
 labs(title="Perceived Debt Before and After CSP 2024") + 
 scale_fill_manual(values=c("darkblue","lightblue"))

Image

As you can see, the percentages across both groups add to 100%, but what I'd really like is for the percentages to add to 100% within groups (Pre-CSP and Post-CSP). Any ideas on how to do so?

Note: the x axis has been relabeled from the data. That is, 1 in column 'd' represents as $0, 2 in column 'd' represents as '$1 to $10,000', and so on.


Solution

  • Untested because I don't have the data, but something like this should work. You're probably best off aggregating the data yourself and then plotting the aggregated data using stat="identity" in the call to geom_bar().

    data %>% 
    group_by(e, d) %>% 
    tally() %>%
    group_by(e) %>% 
    mutate(pct = n/sum(n)) %>% 
    ggplot(aes(x=d,y=pct,fill=forcats::fct_rev(e))) + 
     geom_bar(stat = "identity", position="dodge") + 
     scale_y_continuous(labels = scales::percent) +
     theme(panel.grid.major.y = element_line(color="gray"),
        panel.background =element_blank(), 
        axis.line=element_line("black"), 
        axis.text.x=element_text(face="bold"), 
        legend.title=element_blank(), 
        axis.title.y=element_blank(), 
        axis.title.x=element_blank(),
        plot.title = element_text(hjust = 0.5)
     ) +
     scale_x_discrete(
       labels=c('$0', '$1 to $10K', 'Over $10K to $20K', 'Over $20K to $30K','Over $30K to $40K','Over $40K to $50K','Over $50K')
     ) +
     geom_text(aes(label = scales::percent(round(pct, 2)),y= round(pct, 2)), 
                    position = position_dodge(width = .9),
                    vjust = -1) + 
     labs(title="Perceived Debt Before and After CSP 2024") + 
     scale_fill_manual(values=c("darkblue","lightblue"))