forcats::fct_reorder()
   get_help()
docs
The fct_reorder()
function is part of the {forcats}
package, which is part of the {tidyverse}
.
We use the fct_reorder()
function to quickly reorder of categories (levels) in a factor variable based on the order of values in another variable.
Changing the order of factor levels is commonly performed to change axis order of a factor variable when using plotting with the {ggplot2}
library.
To use this function, you need to either first load the {forcats}
library, or always use the function with forcats::fct_reorder()
notation.
# Load the library
library(forcats)
# Or, load the full tidyverse:
library(tidyverse)
# Or, use :: notation
::fct_reorder() forcats
fct_reorder(factor variable to change order of, other variable to order by)
fct_reorder(factor variable to change order of,
other variable to order by, # Commonly used optional arguments:
.fun = how to transform the other variable for re-ordering,
.desc = TRUE or FALSE) # Ordered in descending order, by default
The examples below use a modified version of the msleep
dataset called msleep_fctvore
. Learn more about this dataset with get_help("msleep")
.
In this modified dataset, the vore
column has been coerced into a factor type (instead of character), and all NA
values have been removed from that column. (Notice below, the vore
column is annotated <fct>
since it’s a factor).
# Show the modified msleep dataset, msleep_fctvore, with head()
head(msleep_fctvore)
## # A tibble: 6 × 11
## name genus vore order conservation sleep_total sleep_rem sleep_cycle awake brainwt bodywt
## <chr> <chr> <fct> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Owl … Aotus omni Prim… <NA> 17 1.8 NA 7 0.0155 0.48
## 2 Moun… Aplo… herbi Rode… nt 14.4 2.4 NA 9.6 NA 1.35
## 3 Grea… Blar… omni Sori… lc 14.9 2.3 0.133 9.1 0.00029 0.019
## 4 Cow Bos herbi Arti… domesticated 4 0.7 0.667 20 0.423 600
## 5 Thre… Brad… herbi Pilo… <NA> 14.4 2.2 0.767 9.6 NA 3.85
## 6 Nort… Call… carni Carn… vu 8.7 1.4 0.383 15.3 NA 20.5
# Examples will reorder based on mean(awake), so this shows what to expect:
# Calculate and show the values of mean(awake) per vore.
%>%
msleep_fctvore group_by(vore) %>%
summarize(mean_awake = mean(awake)) %>%
arrange(mean_awake)
## # A tibble: 4 × 2
## vore mean_awake
## <fct> <dbl>
## 1 insecti 7.48
## 2 omni 13.0
## 3 carni 14.3
## 4 herbi 14.9
# reorder the order of `vore` levels according to _mean_ values of _awake_
%>%
msleep_fctvore mutate(vore = fct_reorder(vore,
awake, # This argument tells forcats to order vore by MEAN awake
.fun = mean)) -> msleep_fctvore_ex1
# Show new levels to confirm they are updated
levels(msleep_fctvore_ex1$vore)
## [1] "insecti" "omni" "carni" "herbi"
# reorder the order of `vore` levels according to _mean_ values of _awake_, but in descending order
%>%
msleep_fctvore mutate(vore = fct_reorder(vore,
awake, .fun = mean, # order vore by MEAN awake
.desc = TRUE)) -> msleep_fctvore_ex2
# Show new levels to confirm they are updated
levels(msleep_fctvore_ex2$vore)
## [1] "herbi" "carni" "omni" "insecti"
# reorder the order of `vore` levels according to _mean_ values of _awake_,
# Here, we first summarize the data so we need only to reorder by `mean_awake`, without needing a `.fun` argument
%>%
msleep_fctvore group_by(vore) %>%
summarize(mean_awake = mean(awake)) %>%
mutate(vore = fct_reorder(vore, mean_awake)) -> msleep_fctvore_ex3
# Show new levels to confirm they are updated
levels(msleep_fctvore_ex3$vore)
## [1] "insecti" "omni" "carni" "herbi"
# Without re-writing the column, change the levels for _plotting purposes only_
# Provide fct_reorder(VARIABLE, OTHER VARIABLE, ...) to ggplot2::aes() to order in your plot
# This affects the x-axis labeling, so it is best practice to clean up with `labs()`
# For this plot, we'll reorder `vore` based on MINIMUM AWAKE values
# Recall: The R function to calculate minimums is `min()`
ggplot(msleep_fctvore) +
aes(x = fct_reorder(vore, awake, .fun = min),
y = awake) +
geom_boxplot() +
labs(x = "vore")
# Without re-writing the column, change the levels for _plotting purposes only_
# Provide fct_reorder(VARIABLE, OTHER VARIABLE, ...) to ggplot2::aes() to order in your plot
# This affects the x-axis labeling, so it is best practice to clean up with `labs()`
# For this plot, we'll reorder `vore` based on its COUNT, using `dplyr::count()`
%>%
msleep_fctvore count(vore) %>%
ggplot() +
aes(x = fct_reorder(vore, n),
y = n) +
geom_col() +
labs(x = "vore")