Как построить большое количество графиков плотности с разными категориальными переменными

#r #ggplot2 #density-plot

#r #ggplot2 #плотность-график

Вопрос:

У меня есть набор данных, в котором у меня есть одна числовая переменная и много категориальных переменных. Я хотел бы создать сетку графиков плотности, каждый из которых показывает распределение числовой переменной для разных категориальных переменных, с заливкой, соответствующей подгруппам каждой категориальной переменной. Например:

 library(tidyverse)
library(nycflights13)

dat <- flights %>%
  select(carrier, origin, distance) %>%
  mutate(origin = origin %>% as.factor,
         carrier = carrier %>% as.factor)

plot_1 <- dat %>%
  ggplot(aes(x = distance, fill = carrier))  
  geom_density()

plot_1

plot_2 <- dat %>%
  ggplot(aes(x = distance, fill = origin))  
  geom_density()

plot_2
  

Я хотел бы найти способ быстро построить эти два графика. На данный момент единственный известный мне способ сделать это — создать каждый график по отдельности, а затем использовать grid_arrange для их объединения. Однако мой реальный набор данных содержит что-то вроде 15 категориальных переменных, так что это займет очень много времени!

Есть ли более быстрый и простой способ сделать это? Я считаю, что самое сложное в этом заключается в том, что у каждого графика есть своя легенда, поэтому я не уверен, как обойти этот камень преткновения.

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

1. Пожалуйста, предоставьте примерные данные. Я думаю, вам следует преобразовать «данные ширины» в «длинные данные», а затем использовать facet_wrap для построения графика.

2. В моем сообщении есть воспроизводимый пример?

Ответ №1:

Это решение предоставляет все графики в списке. Здесь мы создаем единую функцию, которая принимает переменную, которую вы хотите построить, а затем используем lapply с вектором всех переменных, которые вы хотите построить.

 fill_variables <- vars(carrier, origin)

func_plot <- function(fill_variable) {
  dat %>%
  ggplot(aes(x = distance, fill = !!fill_variable))  
  geom_density()
}

plotlist <- lapply(fill_variables, func_plot)
  

Если вы понятия не имеете, что это !! значит, я рекомендую посмотреть это 5-минутное видео, в котором представлены ключевые концепции аккуратной оценки. Это то, что вы хотите использовать, когда хотите создать такие функции-оболочки, чтобы делать что-то программно. Надеюсь, это поможет!


Редактировать: если вы хотите передать массив строк вместо запроса, вы можете изменить !!fill_variable !!sym(fill_variable) его следующим образом:

 fill_variables <- c('carrier', 'origin')

func_plot <- function(fill_variable) {
  dat %>%
    ggplot(aes(x = distance, fill = !!sym(fill_variable)))  
    geom_density()
}

plotlist <- lapply(fill_variables, func_plot)
  

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

1. Вы — это все, что есть хорошего в мире. Большое спасибо! 🙂

2. Одно быстрое продолжение. У меня возникли проблемы с передачей имен столбцов в ‘fill_variables’. Прямо сейчас я извлекаю имена столбцов, используя следующий код: flights_cat <- flights_subset %>% sapply(is.factor) %>% which() flights_cat_names <- flights_subset %>% select(flights_cat) %>% colnames Вы знаете, как я могу передать этот вектор имен столбцов в ‘vars’?

Ответ №2:

Альтернативное решение

Как написал @djc в комментариях, I'm having trouble passing the column names into 'fill_variables'. Right now I am extracting column names using the following code...

Вы можете разделить категориальные и числовые переменные, такие как; cat_vars <- flights[, sapply(flights, is.character)] для категориальных переменных и cat_vars <- flights[, sapply(flights, !is.character)] для непрерывных переменных, а затем передать эти векторы в функцию-оболочку, заданную mgiormenti

Полный код приведен ниже;

 library(tidyverse)
library(nycflights13)

cat_vars <- flights[, sapply(flights, is.character)]
cont_vars<- flights[, !sapply(flights, is.character)]
dat <- flights %>%
  select(carrier, origin, distance) %>%
  mutate(origin = origin %>% as.factor,
         carrier = carrier %>% as.factor)

func_plot_cat <- function(cat_vars) {
  dat %>%
    ggplot(aes(x = distance, fill = !!cat_vars))  
    geom_density()
}

func_plot_cont <- function(cont_vars) {
  dat %>%
    ggplot(aes(x = distance, fill = !!cont_vars))  
    geom_point()
}

plotlist_cat_vars <- lapply(cat_vars, func_plot_cat)
plotlist_cont_vars<- lapply(cont_vars, func_plot_cont)
print(plotlist_cat_vars)
print(plotlist_cont_vars)