Tiptop
Tiptop

Reputation: 623

Ordering of stacked bars according to first facet in ggplot2

I'm doing stacked bars plots and I have a code that orders the bars according to the percentage of the first variable "TERP". When I'm faceting this plot the order of bars is reordered according to "TERP" for each facet, however I would like that bars had the same order in each facet. So only for the first facet would the bars be ordered according to the percentage of "TERP". In the first facet the order of bars should be 4, 1, 3, 2 and likewise in the second facet.

Any ideas as how to do this would be much appreciated.

Here's the data:

library(tidyverse)
library(ggplot2)

my_df <- structure(list(group2 = c("CxHy", "CxHy", "CxHy", "CxHy", "CxHy", 
                                   "CxHy", "CxHy", "CxHy", "TERP", "TERP", "TERP", "TERP", "TERP", 
                                   "TERP", "TERP", "TERP", "CxHy", "CxHy", "CxHy", "CxHy", "CxHy", 
                                   "CxHy", "CxHy", "CxHy", "TERP", "TERP", "TERP", "TERP", "TERP", 
                                   "TERP", "TERP", "TERP"), rate = c(35.0413764604317, 1.581780096, 
                                                                     48.1546154514286, 5.6177417568, 118.07707609554, 9.78168399744, 
                                                                     125.236895496, 8.71879325664, 137.594582077252, 14.0889705513239, 
                                                                     630.450644424867, 42.8764673332745, 752.039882591234, 23.2549865965314, 
                                                                     1385.89284580167, 77.9737494781406, 0, 0, 0, 0.51091296192, 12.1578219080288, 
                                                                     1.121021002368, 26.1570828734857, 0.958406204448, 311.87378680008, 
                                                                     41.0741226543657, 889.66751457975, 32.9591458117879, 667.747148244659, 
                                                                     26.9290441959229, 1343.81735772991, 39.2757060997948), jar1 = c("1", 
                                                                                                                                     "2", "3", "4", "1", "2", "3", "4", "1", "2", "3", "4", "1", "2", 
                                                                                                                                     "3", "4", "1", "2", "3", "4", "1", "2", "3", "4", "1", "2", "3", 
                                                                                                                                     "4", "1", "2", "3", "4"), days_incubated = c(0L, 0L, 0L, 0L, 
                                                                                                                                                                                  4L, 4L, 4L, 4L, 0L, 0L, 0L, 0L, 4L, 4L, 4L, 4L, 0L, 0L, 0L, 0L, 
                                                                                                                                                                                  4L, 4L, 4L, 4L, 0L, 0L, 0L, 0L, 4L, 4L, 4L, 4L)), row.names = c(NA, 
                                                                                                                                                                                                                                                  -32L), class = "data.frame")

And here's the code for the graph:

df_sum <- my_df %>% 
  group_by(jar1, group2, days_incubated) %>% 
  summarise(sum_rate=sum(rate)) %>% 
  group_by(days_incubated, jar1) %>% 
  mutate(sum_jar1=sum(sum_rate)) %>% 
  mutate(rel_jar1=sum_rate/sum_jar1) %>% 
  group_by(days_incubated, jar1) %>% 
  mutate(perc_terp=rel_jar1[group2=="TERP"]) %>% 
  mutate(group2=fct_inorder(group2) %>% 
  fct_rev())

#> `summarise()` regrouping output by 'jar1', 'group2' (override with `.groups` argument)

levels(df_sum$group2)
#> [1] "TERP" "CxHy"

df_sum %>% 
  ggplot()+
  geom_bar(aes(x=tidytext::reorder_within(
    x=jar1,
    by=perc_terp,
    within=days_incubated),
    y=sum_rate,
    fill=group2),
    position="fill",
    stat="identity")+
  facet_wrap(vars(days_incubated),
  scale="free_x")+
  tidytext::scale_x_reordered()+
  theme_bw() + 
  theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.4), 
  axis.text=element_text(size=7))

Upvotes: 1

Views: 69

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 173878

We can just reorder jar1 and plot it without the scale_x_reordered:

df_sum %>% 
  mutate(jar1 = factor(jar1, 
                       levels = df_sum %>% 
                                filter(group2 == "TERP", days_incubated == 0) %>% 
                                pluck("perc_terp") %>% 
                                order())) %>%
  ggplot() +
  geom_col(aes(x = jar1, y = sum_rate, fill = group2), position = "fill") +
  facet_wrap(vars(days_incubated)) +
  theme_bw() + 
  theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.4), 
        axis.text = element_text(size = 7))

enter image description here

Upvotes: 1

Related Questions