Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R: reorder factor levels for several individual plots

Tags:

r

dplyr

ggplot2

I am trying to create several individual plots from the same data.frame with a different order of the factor levels on the y axis for each plot. Each plot is supposed to order the factor levels on y decreasingly.

I know that this can be done manually for each plot but I am looking for a more efficient and elegant way since I'll have quite a number of plots that I need to create. This doesn't have to include the use of of facet_wrap, if there is another way, maybe with loops etc.?

library(ggplot2)
library(dplyr)
data("diamonds")

Taking the data set and aggregating by two factor levels (clarity and cut):

means <- diamonds %>%
group_by(clarity, cut) %>%
summarise(carat = mean(carat))

Here I reorder by mean of one factor but eventually I would like to reorder separately for each plot (by decreasing mean of clarity).

means$clarity <- reorder(means$clarity, means$carat, FUN = mean)

Creating separate plots with face_wrap. Using coord_flip to compare plots more easily.

ggplot(means, aes(x = clarity, y = carat)) +
  geom_col() +
  facet_wrap(~cut, ncol = 1) +
  coord_flip()

You'll see that this creates separate plots for each type of cut but the order of the factor levels on the y axis are not correct for each individual case. How can I order them correctly without having to do that manually for each type of cut?

like image 479
SveaM Avatar asked Nov 30 '17 12:11

SveaM


People also ask

How do you reorder the levels of a factor in R?

One way to change the level order is to use factor() on the factor and specify the order directly. In this example, the function ordered() could be used instead of factor() . Another way to change the order is to use relevel() to make a particular level first in the list.

What does Fct_reorder do in R?

fct_reorder() is useful for 1d displays where the factor is mapped to position; fct_reorder2() for 2d displays where the factor is mapped to a non-position aesthetic. last2() and first2() are helpers for fct_reorder2() ; last2() finds the last value of y when sorted by x ; first2() finds the first value.

What function in the forcats package can be used to reorder the levels of a factor in any order you want?

We can use the function fct_relevel() when we need to manually reorder our factor levels. In addition to the factor, you give it a character vector of level names, and specify where you want to move them.


1 Answers

This can be done in one plot by utilizing two functions:

reorder_within <- function(x, by, within, fun = mean, sep = "___", ...) {
  new_x <- paste(x, within, sep = sep)
  stats::reorder(new_x, by, FUN = fun)
}


scale_x_reordered <- function(..., sep = "___") {
  reg <- paste0(sep, ".+$")
  ggplot2::scale_x_discrete(labels = function(x) gsub(reg, "", x), ...)
}

available on github dgrtwo/drlib

ggplot(means, aes(x = reorder_within(clarity, carat, cut, mean), y = carat)) + 
  geom_col() + 
  scale_x_reordered() +
  facet_wrap(~cut,  scales = "free_y", ncol = 1) +
  coord_flip()

enter image description here

like image 194
missuse Avatar answered Sep 21 '22 20:09

missuse