How to reorder barplots with facetting with ggplot2 in R?

Reordering barplots with facet : Using reorder_within()
Reordering barplots with facet : Using reorder_within()

Reordering bars in barplot either in ascending or descending order can help quickly see how the groups/categories vary. When you have a thrid variable, adding facet to the barplot can be very useful. In this tutorial, we will see how to reorder bars in barplot with facetting by a thrid variable using ggplot2 in R.

Let us load tidyverse and set the theme for our plots.

library(tidyverse)
theme_set(theme_bw(base_size=16))

We will use tidytuesday dataset on how US states spend on kids over time. Let us load the dataset directly from tidytuesday’s github page.

kids <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-09-15/kids.csv')
## Parsed with column specification:
## cols(
##   state = col_character(),
##   variable = col_character(),
##   year = col_double(),
##   raw = col_double(),
##   inf_adj = col_double(),
##   inf_adj_perchild = col_double()
## )

This is how our data looks like.

kids %>% head()
## # A tibble: 6 x 6
##   state      variable  year      raw   inf_adj inf_adj_perchild
##   <chr>      <chr>    <dbl>    <dbl>     <dbl>            <dbl>
## 1 Alabama    PK12ed    1997  3271969  4665308.             3.93
## 2 Alaska     PK12ed    1997  1042311  1486170              7.55
## 3 Arizona    PK12ed    1997  3388165  4830986.             3.71
## 4 Arkansas   PK12ed    1997  1960613  2795523              3.89
## 5 California PK12ed    1997 28708364 40933568              4.28
## 6 Colorado   PK12ed    1997  3332994  4752320.             4.38


We will use inflation adjusted dollars spent per child across 50 states for years 2010 and 2015. Let us try to make barplot between state and the inflation adjusted dollars with years as facetting variable.

To reorder state by dollars per child, we use fct_reorder() function from forcats package first.

kids %>%
  drop_na()%>%
  filter(year %in% c(2010,2015))%>%  
  mutate(state=fct_reorder(state,inf_adj_perchild))%>%
  ggplot(aes(y=state,
             x=inf_adj_perchild))+
  geom_col()+
  facet_wrap(~year)+
  labs(y="state")

And this is how our reordered barplots with facetting looks like. Note that, we have a common y-axis. However, looking at it carefully we can see that that the states are not correctly ordered.

Reordering barplots with facet: : First try

We will see similar behaviour even after changing y-axis scales with scale=’free_y’ option to facet_wrap().

tidytext, the R package made by Robinson and Silge has an easy solution to reordering with facetting. Let us load tidytext package.

library(tidytext)

Two key functions that will help with reordering and facetting are “reorder_within” and “scale_y_reordered”. At first, we use reorder_within() function as shown below to reorder bars within in each facet. And then we use scale_y_reordered() to clean up the y-axis variable names on the plot.


kids %>%
  drop_na()%>%
  filter(year %in% c(2010,2015))%>%  
  mutate(state = reorder_within(state,inf_adj_perchild, year)) %>%
  ggplot(aes(y=state,
             x=inf_adj_perchild))+
  geom_col()+
  scale_y_reordered() +
  facet_wrap(~year,scales="free_y")+
  labs(y="state")

Now we have reordered barplots with the facetting variable. Notice that that the bars in each barplot is nicely ordered. Also we can see that y-axis label is different in the example.

Reordering barplots with facet : Using reorder_within()
Exit mobile version