Home > Software engineering >  ggplot - geom_bar with subgroups stacked
ggplot - geom_bar with subgroups stacked

Time:05-19

I am trying to create a graph in ggplot where the there is a separation between Round1 and Round2 while being able to differentiate between the refreshment pool in Round2. I am trying to do with without using facet wrap or grid do to presentation issues.

data.frame(Var1=c("old ","old ","old ","middle", "middle", "middle", "young", "young", "young"),
Round=c(1,2,2,1,2,2,1,2,2),
Refreshment=c(0,0,2,0,0,2,0,0,2),
Round_Refr=c(1.0,2.0,2.2,1.0,2.0,2.2,1.0,2.0,2.2),
pertotal=c(0.199, 0.196, 0.031, 0.459, 0.461, 0.020, 0.342, 0.343, 0.032))

The closest I have gotten is this - However it is treating each category(Round and age group as a different group on the X axis) And is adding the refreshment round on top of Round two, rather than treating it as if it is apart of the Round.

    ggplot(data, aes(x = (interaction(Round,Var1)), y = pertotal))   
       geom_bar(aes(fill = Round_Refr),stat = "identity",color="white") 
       scale_y_continuous(labels=percent)  xlab("category") 
      ylab("Percent of ")  labs(fill = "Round") 
       ggtitle("Plot") 
      theme(plot.title = element_text(hjust = 0.5)

enter image description here

Do you know of a way to make it look more like the graph below? Where they are still grouped by Age/ Round and there is a delineation between Round2's refreshment pool and the rest of the respondents.

enter image description here

CodePudding user response:

This is possible but requires a bit of sleight-of-hand. You would need to use a continuous x axis and label it like a discrete axis. This requires a bit of data manipulation:

library(tidyverse)

data %>%
  mutate(category = as.numeric(interaction(Round,Var1)),
         category = category   (category %% 2)/5 - 0.1,
         Round_cat = factor(Round_Refr, labels = c("1", "2", "Break")),
         Round_cat = factor(Round_cat, c("Break", "1", "2"))) %>%
  group_by(Var1, Round) %>%
  mutate(pertotal = ifelse(Round == 2 & Refreshment == 0,
                           pertotal - pertotal[Round_Refr > 2], pertotal)) %>%
  ggplot(aes(x = category, y = pertotal))   
  geom_col(aes(fill = Round_cat), color="white") 
  scale_y_continuous(labels=scales::percent)  
  scale_x_continuous(breaks = c(1.5, 3.5, 5.5), 
                     labels = levels(factor(data$Var1)))  
  xlab("category") 
  ylab("Percent of ")  
  labs(fill = "Round") 
  ggtitle("Plot") 
  scale_fill_brewer(palette = "Set1")  
  theme_light(base_size = 16)  
  theme(plot.title = element_text(hjust = 0.5))

enter image description here

  • Related