Reorder levels of a categorical variable within panels according to the group to which they belong

Asked

Viewed 110 times

5

When using the command fct_reorder(class, hwy, .fun = median) below, I asked for the variable levels class were reordered according to median variable hwy:

library(tidyverse)

ggplot(mpg, aes(x = fct_reorder(class, hwy, .fun = median), y = hwy)) +
  geom_boxplot() +
  facet_wrap(~ year) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(x = "class")

Created on 2021-08-09 by the reprex package (v2.0.1)

However, the levels of class were reordered according to the general medians of class, and not of class for year. That is, the panel referring to 1999 appears, by chance, as desire, but the panel referring to 2008 does not. The order of Compact and midsize is altered.

How can I make fct_reorder understand that you would like to reorder your levels by more than one variable in sequence?

1 answer

4


The function tidytext::reorder_within do what you need to do:

library(ggplot2)
library(tidytext)

ggplot(mpg, aes(x = reorder_within(class, by = hwy, within = year, fun = median), y = hwy)) +
  geom_boxplot() +
  facet_wrap(~ year, scales = "free_x") +
  scale_x_reordered() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(x = "class")

inserir a descrição da imagem aqui

The "trick" below it is to create a new factor by pasting the variable to be ordered and the grouping variable. A scale_x_reordered removes the group name of the factor. The equivalent with fct_reorder would be:

library(ggplot2)
library(forcats)

ggplot(mpg, aes(x = fct_reorder(paste(class, year, sep = ":"), hwy, .fun = median), y = hwy)) +
  geom_boxplot() +
  facet_wrap(~ year, scales = "free_x") +
  scale_x_discrete(labels = function(x) gsub(":.*", "", x)) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(x = "class")

Alternatively, one can use interaction instead of paste:

ggplot(mpg, aes(x = fct_reorder(interaction(class, year), hwy, .fun = median), y = hwy)) +
  geom_boxplot() +
  facet_wrap(~ year, scales = "free_x") +
  scale_x_discrete(labels = function(x) gsub("\\..*", "", x)) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(x = "class")
  • The idea of creating a new factor by pasting class and year is very good. I liked this strategy.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.