упорядочить / упорядочить geom_boxplot или geom_bar по двум другим столбцам

#r #ggplot2 #dplyr

#r #ggplot2 #dplyr

Вопрос:

Я пытаюсь изменить порядок моей оси x для boxplot. Я знаю, что могу упорядочить графики, изменив порядок коэффициента, используемого в качестве эстетики x. Я могу сделать это, используя значения из другого столбца, используя reorder или forcats::fct_reorder , но как я могу изменить порядок, используя значения из двух столбцов? Вот пример набора данных:

 df <- tibble::tribble(
  ~name,        ~mod, ~dil,
  "LiveGas",     1,    0,
  "DilLiveGas",  1,    3,
  "DilLiveGas1", 1,    1,
  "DeadGas",     0,    0,
  "DilDeadGas",  0,    3,
  "DilDeadGas1", 0,    1
)
 

Порядок, который я хотел бы, задан arrange(df, mod, dil) :

 # A tibble: 6 x 3
  name          mod   dil
  <chr>       <dbl> <dbl>
1 DeadGas         0     0
2 DilDeadGas1     0     1
3 DilDeadGas      0     3
4 LiveGas         1     0
5 DilLiveGas1     1     1
6 DilLiveGas      1     3
 

Я посмотрел forcats::fct_reorder2(df$name, df$dil, df$mod) , но мне явно чего-то не хватает в том, как работает эта функция.

В реальном наборе данных намного больше строк с полем значения, используемым для создания boxplot. Я могу добавить это, если это полезно, но как только я правильно упорядочу name , это должно встать на свои места.

Комментарии:

1. interaction(mod, dil) Возможно, использовать?

2. interaction() дает правильный порядок коэффициентов, но я не понимаю, как применить эти уровни name .

Ответ №1:

Вам необходимо изменить порядок уровней коэффициентов name в соответствии с вашим расположением:

 namevec <- arrange(df, mod, dil) %>%
  pull(name) 
df$name <- factor(df$name,level = namevec)
 

Затем он должен упорядочить ось x так, как вы хотите:

 df %>%
  ggplot(aes(name,dil,fill = as.factor(mod))) 
  geom_col() 
  theme(axis.text.x = element_text(angle = 45,hjust = 1))
 

введите описание изображения здесь

Комментарии:

1. Спасибо! Этот метод сработал. Поскольку реальный набор данных содержит несколько строк для каждого уровня фактора, мне нужно было получить вектор уникальных уровней следующим образом: `namevec <- arrange(df, mod, dil) %>% pull(name) %>% unique() . Все еще ищу более эффективное решение, если df большой.

Ответ №2:

Похоже, вы ожидаете forcats::fct_reorder2 , что будете функционировать так, как будто вы переупорядочиваете уровни факторов, упорядочивая аргумент 2 с разрывом связей с аргументом 3.

На самом деле происходит то, что функция в аргументе 4 применяется поэлементно к аргументам 2 и 3. Аргумент 4 должен быть функцией, которая принимает 2 аргумента. Значение по умолчанию — forcats::last2 это просто .y[order(.x, na.last = FALSE)][length(.y)] . В целом, не полезно для вашего использования.

Вместо этого я бы предложил базу R base::factor для этой задачи.

 ggplot(df, aes(x = factor(name, levels = name[order(mod,dil)]),
               y = dil, fill = as.factor(mod)))  
  geom_col()  
  labs(x = "name", fill = "mod")
 

введите описание изображения здесь

Комментарии:

1. Это объяснение fct_reorder2() намного понятнее, чем в документах forcats . Мне нужно было обернуть ваш бит генерации уровня в unique() для обработки нескольких строк на фактор в моем реальном df следующим образом: factor(name, levels = unique(name[order(mod, dil)])).