akang
akang

Reputation: 651

ggplot: Order stacked barplots by variable proportion

I am creating a plot with 3 variables as below. Is there a way to arrange the plot in a descending order such that the bar with the highest proportion of variable "c" comes first in the plot. Using this example last bar should come in first then middle one and then the first bar in the last.

long<- data.frame(
      Name = c("abc","abc","abc","gif","gif","gif","xyz","xyz","xyz"),
      variable = c("a","b","c","a","b","c","c","b","a"),
      value = c(4,6,NA,2,8,1,6,NA,NA))
    
    
long_totals <- long %>%
      group_by(Name) %>%
      summarise(Total = sum(value, na.rm = T))
    
    p <- ggplot()+
      geom_bar(data = long,
               aes(x = Name, 
                   y = value,
                   fill=variable),
               stat="summary", 
               position = "fill") +
      geom_text(data = long_totals,
                aes(y = 100,
                    x = Name,
                    label = Total),
                size = 7,
                position = position_fill(vjust = 1.02)) +
      scale_y_continuous(labels = scales::percent_format()) +
      ylab("Total_num") +
      ggtitle("Totalnum") +
      theme(plot.title = element_text(size = 20, hjust = 0.5)) +
      theme(axis.text.x = element_text(angle = 75, vjust = 0.95, hjust=1)) 

The following code does arrange the bars by count of "c" but not by proportion. How can I arrange by proportion?

    p<-long %>%
mutate(variable = fct_relevel(variable, 
                                    c("c", "b", "a"))) %>%
      
      arrange(variable) %>%        
      mutate(Name = fct_inorder(Name))  
      
      p %>% 
      ggplot() +
      aes(x = Name,
          y = value,
          fill = variable) +
      geom_bar(position = "fill",
               stat = "summary") + 
      

Upvotes: 0

Views: 48

Answers (1)

TarJae
TarJae

Reputation: 79311

We could use fct_rev from forcats package, it is in tidyverse:

p <- ggplot()+
  geom_bar(data = long,
           aes(x = fct_rev(Name), 
               y = value,
               fill=variable),
           stat="summary", 
           position = "fill") +
  geom_text(data = long_totals,
            aes(y = 100,
                x = Name,
                label = Total),
            size = 7,
            position = position_fill(vjust = 1.02)) +
  scale_y_continuous(labels = scales::percent_format()) +
  ylab("Total_num") +
  ggtitle("Totalnum") +
  theme(plot.title = element_text(size = 20, hjust = 0.5)) +
  theme(axis.text.x = element_text(angle = 75, vjust = 0.95, hjust=1)) 

enter image description here

Upvotes: 2

Related Questions