Search code examples
rggplot2facet-wrap

Adding bar labels - faceted plot of proportions


My dataframe is formatted like this:

data <- data.frame(district = c("South", "North", "North", "West", "South", "South", "West"), response = c(2,3,5,4,4,3,3))

I've created this plot, which compares the proportion of positive responses in each district.

data %>%
  mutate(response = case_when(response < 3.5 ~ "no/neutral",
                              response > 3.5 ~ "yes")) %>% 
  ggplot(aes(x = response, fill = response)) +
  scale_fill_manual(values = c("#E69F00", "#009E73")) +
  theme(legend.position="none") +
  geom_bar(aes(y = (..count..)/tapply(..count..,..PANEL..,sum)[..PANEL..])) +
  facet_wrap(vars(district)) +
  labs(x = "Response", y = "Proportion")

I'd like to add a label to the top of each bar to display the exact proportion of responses it displays. I've tried using geom_text() but I'm not sure what my aesthetics y and label should be.


Solution

  • I have modified your code a little: First of all we calculate the proportions before plotting. Then we use geom_col()

    library(tidyverse)
    
    data %>%
      mutate(response = case_when(response < 3.5 ~ "no/neutral",
                                  response > 3.5 ~ "yes")) %>% 
      group_by(district, response) %>%
      summarise(n = n()) %>%
      mutate(freq = n / sum(n)) %>% 
      mutate(label.freq = paste0(round(100 * n/sum(n), 0), "%")) %>% 
      ggplot(aes(x = response, y = freq, fill = response)) +
      geom_col(position=position_dodge())+
      scale_fill_manual(values = c("#E69F00", "#009E73")) +
      facet_wrap(vars(district)) + 
      geom_text(aes(label = label.freq),  position = position_dodge(width = 0.9), vjust = -0.25,
                lineheight = 0.9)+
      labs(x = "Response", y = "Proportion")
      theme(legend.position="none")
    

    enter image description here