Ruben Ruben - 17 days ago 9
R Question

dodged bar chart with stack for the total

I would like to add a stacked bar to a dodged bar chart, showing the total. I don't want the column for the total to be a solid bar, but to consist of the stacked components.
I can add both geom_bars to the plot, but I haven't been able to move the total bar. I could add a dummy category with zero in the middle, but of course I'd prefer the total to be to the right of the components.

df=data.frame(
treatment=rep(c("Impact","Control")),
type=rep(c("Phylum1","Phylum2"),each=2),
total=c(2,3,4,5))

ggplot(df,aes(y=total,x=treatment,fill=type)) +
geom_bar(position= position_dodge(),stat="identity", alpha = 0.9, width = 0.25) +
geom_bar(position = position_stack(), stat = 'identity', alpha = 0.3, width = 0.125)


not precisely what I want

This is not the same question they want to stack/dodge by two variables. I just want to summarise the same info twice, but differently.

I can of course add a bar for the solid total and put in the stacked bar by hand, but I get so close with basic ggplot that I thought maybe a little hack (e.g. modifying the return object of position_stack) might be possible.

Answer

You could reshape your dataset and use facets to get the effect, although this will show all of your data and not just the largest value in each type/treatment combination.

Your dataset would need to be repeated twice, once for the the original type and once for plotting the totals. You also need a new variable, which I called type2.

df$type2 = df$type
df2 = df
df2$type2 = "Total"

Stack the two datasets together via rbind, and then plot using type2 as the x variable and the alpha variable.

ggplot(rbind(df, df2), aes(y = total, x = type2, fill = type, alpha = type2)) + 
    geom_col(width = .9) +
    facet_wrap(~treatment, strip.position = "bottom") +
    scale_alpha_manual(values = c(.9, .9, .3), guide = "none") +
    theme(strip.background = element_blank(),
          axis.text.x = element_blank(),
          axis.ticks.length = unit(0, "mm"),
          panel.spacing = unit(0, "mm"),
          panel.grid.major.x = element_blank()) +
    scale_x_discrete(expand = c(1, 0))

enter image description here

Comments