Search code examples
rggplot2geom-bar

How to use multiple position arguments with geom_bar()


I have the following data frame:

year = rep(c(2019,2020), 2)
month = rep(c("June","July"), 2)
male = c(11,13,15,17)
female = c(12,14,16,18)

df <- data.frame(cbind(year, month, male, female))

  year month male female
1 2019  June   11     12
2 2020  July   13     14
3 2019  June   15     16
4 2020  July   17     18

I would like to display the data in a bar chart such that I use "dodge" position for the year column and that for each year there are to bars next to each other for the months June and July which are themselve composed of two stacked bars for the two genders. Any suggestions how to achieve this?


Solution

  • You could facet on the year:

    library(tidyr)
    library(dplyr)
    df %>%
      pivot_longer(c(male,female), names_to="Sex") %>%
      mutate(value=as.numeric(value), month=factor(month, levels=c("June","July"))) %>%
    ggplot(aes(month, value, fill=Sex)) +
      geom_bar(stat="identity", position=position_stack()) +
      facet_grid(~year, switch="x") + theme_minimal()
    

    enter image description here

    And if you think it would look better with the month labels above the year labels, you can adjust the axis.text.

    df %>%
      pivot_longer(c(male,female), names_to="Sex") %>%
      mutate(value=as.numeric(value),
             month=factor(month, levels=c("June","July")),
             Month=paste(year,month,sep="-")) %>%
    ggplot(aes(month, value, fill=Sex)) +
      geom_bar(stat="identity", position=position_stack()) +
      theme_minimal() + xlab("") + 
      facet_grid(~year, switch='x') + 
      theme(axis.text.x = element_text(margin = margin(t = -1, unit = "cm")))
    

    enter image description here


    Data:

    df <- structure(list(year = c("2019", "2020", "2019", "2020"), month = c("June", 
    "June", "July", "July"), male = c("11", "13", "15", "17"), female = c("12", 
    "14", "16", "18")), class = "data.frame", row.names = c(NA, -4L))