Home > OS >  R: two item 100% stacked bar chart, percentages not showing correctly
R: two item 100% stacked bar chart, percentages not showing correctly

Time:01-12

My intention is to plot to items into same stacked bar chart as separate bars. The data frame looks like this, and the percentages are correct there.

enter image description here

But the proportions in the bars do not go according to the percentages. Can you find the flaw in my code? enter image description here

plot_data %>%
  drop_na() %>% 
  ggplot(mapping = aes(x = variable))  
  geom_bar(aes(fill = value),
           position = 'fill',
           width = 0.30) 
  scale_y_continuous(name = '% of responders',
                     breaks = seq(from = 0, to = 1, by = 0.2),
                     minor_breaks = seq(from = 0, to = 1, by = 0.1),
                     labels = seq(from = 0, to = 100, by = 20),
                     expand = c(0,0))  
  xlab( element_blank())  
  scale_fill_manual(
    values = c('red', 'blue', 'green'),
    labels = c(
      'Yes',
      'No',
      'Maybe'
    ),
    drop = FALSE
  )  
  
  guides(
    fill = guide_legend(title = 'Answer')
  )   theme(text = element_text(size = 12), 
            panel.background = element_blank(),
            plot.margin = margin(t = 150, r =  30, b = 20, l = 0),
            axis.ticks.y = element_blank(),
            panel.grid.major = element_line(colour = 'grey'),
            axis.ticks.x = element_line(colour = 'grey'),
            panel.grid.minor = element_line(colour = 'lightgrey'),
            axis.text.y = element_text(
              size = 12,
              face = 'plain',
              hjust = 0
            ))  
  coord_flip()  
  ggtitle(str_wrap("Title", width = 50))  
  scale_x_discrete(labels = function(x)
    str_wrap(x, width = 20))

My data:

plot_data <- structure(list(variable = c("Question 1", "Question 1", "Question 1", 
"Question 2", "Question 2", "Question 2"), value = structure(c(1L, 
2L, 3L, 1L, 2L, 3L), .Label = c("Yes", "No", "Maybe"), class = c("ordered", 
"factor")), n = c(102L, 27L, 18L, 78L, 62L, 7L), pct = c(0.693877551020408, 
0.183673469387755, 0.122448979591837, 0.530612244897959, 0.421768707482993, 
0.0476190476190476)), class = c("grouped_df", "tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -6L), groups = structure(list(
    variable = c("Question 1", "Question 2"), .rows = structure(list(
        1:3, 4:6), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -2L), .drop = TRUE))

CodePudding user response:

You could add the pct values as y aes with geom_col and to have an percentage y-axis you could use the percent function from scales like this:

library(ggplot2)
library(dplyr)
library(tidyr)
library(stringr)
plot_data %>%
  drop_na() %>% 
  ggplot(mapping = aes(x = variable))  
  geom_col(aes(fill = value, y = pct),
           position = 'fill',
           width = 0.30) 
  scale_y_continuous(labels = scales::percent)  
  xlab( element_blank())  
  scale_fill_manual(
    values = c('red', 'blue', 'green'),
    labels = c(
      'Yes',
      'No',
      'Maybe'
    ),
    drop = FALSE
  )  
  
  guides(
    fill = guide_legend(title = 'Answer')
  )   theme(text = element_text(size = 12), 
            panel.background = element_blank(),
            axis.ticks.y = element_blank(),
            panel.grid.major = element_line(colour = 'grey'),
            axis.ticks.x = element_line(colour = 'grey'),
            panel.grid.minor = element_line(colour = 'lightgrey'),
            axis.text.y = element_text(
              size = 12,
              face = 'plain',
              hjust = 0
            ))  
  coord_flip()  
  ggtitle(str_wrap("Title", width = 50))  
  scale_x_discrete(labels = function(x)
    str_wrap(x, width = 20))

Created on 2023-01-11 with reprex v2.0.2

  • Related