2

I am trying to make a barplot with a summary bar Total showing the sum of two groups: Pulses, Total and Soybeans.

I know it is possible to achieve it by pre-processing the data to get the sum as a summary by group, I am looking for a stat_summary solution. I am not very familiar with stat_summary(), any advice is welcome as I might have overlooked something...

Reprex:

Data:

df <- structure(list(Year = c(2015L, 2016L, 2017L, 2015L, 2016L, 2017L
), Item = c("Soybeans", "Soybeans", "Soybeans", "Pulses, Total", 
"Pulses, Total", "Pulses, Total"), Value = c(884688L, 829166L, 
960640L, 2219455L, 2354696L, 2683772L)), row.names = c(NA, -6L
), class = "data.frame")

What I've tried so far:

library(ggplot2)

ggplot(data = df, aes(x = Year, y = Value)) +
  stat_summary(
    fun = sum,
    geom = "col",
    position = position_dodge(width = 0.95),
    aes(fill = "Total")
  ) +
  geom_col(
    position = position_dodge(width = 0.95),
    aes(fill = Item)
  )

enter image description here

As you can see, the Total bar does not appear as a 3rd distinct bar. Is it possible to achieve this while keeping the two others and without pre-processing the data?

Expected output:

library(dplyr)
df %>% 
  group_by(Year) %>% 
  summarise(Value = sum(Value), Item = "Total") %>% 
  bind_rows(., df) %>% 
  ggplot(data = ., aes(x = Year, y = Value, fill = Item)) +
  geom_col(position = "dodge")

enter image description here

3
  • Note: geom_col doesn't give you totals of Soybeans / Pulses, Total because you have multiple obs of each group per Year. Commented Aug 4, 2021 at 11:34
  • Hm, I pretty sure that there is a solution, but it will be be much more complicated as your own tidyverse approach. Commented Aug 4, 2021 at 12:24
  • @MartinC.Arnold thanks for your comment, it was not intented, I think the dataset is right now (I forgot a filter when I made it from the true data...). Commented Aug 4, 2021 at 12:45

1 Answer 1

4

You need to use position_nudge(x = ..) on the total column, and set the barwidth accordingly, for example:

library(ggplot2)

barwidth = 0.3
n = length(unique(df$Item))

ggplot(data = df, aes(x = Year, y = Value)) +
  stat_summary(
    fun = sum,
    geom = "col",
    position = position_nudge(x = -1.5*barwidth),
    aes(fill = "Total"),
    width = barwidth
  ) +
  geom_col(
    position = position_dodge(),
    aes(fill = Item),
    width= barwidth * n
  )

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.