Совместное использование ggplot2 и facet_grid для непрерывных и категориальных переменных (R)

#r #ggplot2 #plot #graph #charts

#r #ggplot2 #график #График #Диаграммы

Вопрос:

Я пытаюсь создать серию графиков, подобных этому:

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

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

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

 library(ggplot2) 
library(gridExtra)
library(tidyr)

/create some data/

var_1 <- rnorm(100,1,4)
var_2 <- sample( LETTERS[1:2], 100, replace=TRUE, prob=c(0.3, 0.7) )
var_3 <- sample( LETTERS[1:5], 100, replace=TRUE, prob=c(0.2, 0.2,0.2,0.2, 0.1) )
cluster <- sample( LETTERS[1:4], 100, replace=TRUE, prob=c(2.5, 2.5, 2.5, 2.5) )

/put in a frame/

f <- data.frame(var_1, var_2, var_3, cluster)

/convert to factors/

f$var_2 = as.factor(f$var_2)
f$var_3 = as.factor(f$var_3)
f$cluster = as.factor(f$cluster)

/create graphs/

f2 %>% pivot_longer(cols = contains("var"), names_to = "variable") %>% 
    ggplot(aes(x = value, fill = value))   
    geom_bar()   geom_density()  
    facet_grid(rows = vars(cluster), 
               cols = vars(variable), 
               scales = "free")   
    labs(y = "freq", fill = "Var")
  

Когда у меня есть только категориальные переменные, работает следующий код:

 var_2 <- sample( LETTERS[1:2], 100, replace=TRUE, prob=c(0.3, 0.7) )

var_3 <- sample( LETTERS[1:5], 100, replace=TRUE, prob=c(0.2, 0.2,0.2,0.2, 0.1) )

cluster <- sample( LETTERS[1:4], 100, replace=TRUE, prob=c(2.5, 2.5, 2.5, 2.5) )

f <- data.frame(var_2, var_3, cluster)
f$var_2 = as.factor(f$var_2)
f$var_3 = as.factor(f$var_3)
f$cluster = as.factor(f$cluster)

f%>% pivot_longer(cols = contains("var"), names_to = "variable") %>% ggplot(aes(x = value, fill = value))   geom_bar()   geom_density()  facet_grid(rows = vars(cluster), cols = vars(variable), scales = "free")   labs(y = "freq", fill = "Var")
  

Ответ №1:

Я не думаю, что ggplot может обрабатывать как непрерывные, так и категориальные переменные в y или x эстетическом плане. Но также возникает ошибка при их смешивании в pivot_longer() .

Error: Can't combine `var_1` <double> and `var_2` <character>.

Моей рекомендацией было бы создать отдельные графики для каждой метрики, а затем объединить графики. Это даст вам больший контроль над каждым графиком. Вот пример использования GGally ggmatrix(). Я уверен, что это также возможно с gridextra.

 library(ggplot2)
library(gridExtra)
library(tidyr)
library(GGally)

# Generate data
var_1 <- rnorm(100, 1, 4)
var_2 <- sample(LETTERS[1:2], 100, replace = TRUE, prob = c(0.3, 0.7))
var_3 <- sample(LETTERS[1:5], 100, replace = TRUE, prob = c(0.2, 0.2, 0.2, 0.2, 0.1))
cluster <- sample(LETTERS[1:4], 100, replace = TRUE,prob = c(2.5, 2.5, 2.5, 2.5))

f <- data.frame(var_1, var_2, var_3, cluster)

f$var_2 = as.factor(f$var_2)
f$var_3 = as.factor(f$var_3)
f$cluster = as.factor(f$cluster)

# Create plots for each var
var_1_plot <- f %>%
  ggplot(aes(x = var_1,
             fill = cluster))  
  geom_density()  
  facet_grid(cluster ~ .,
             scales = "free")
var_2_plot <- f %>%
  ggplot(aes(x = var_2,
             fill = cluster))  
  geom_bar()  
  facet_grid(cluster ~ .,
             scales = "free")

var_3_plot <- f %>%
  ggplot(aes(x = var_3,
             fill = cluster))  
  geom_bar()  
  facet_grid(cluster ~ .,
             scales = "free")

# Combine all plots
plot_list <- list(var_1_plot, var_2_plot, var_3_plot)
GGally::ggmatrix(
  plots = plot_list,
  nrow = 1,
  ncol = 3,
  xAxisLabels = c("Var 1", "Var 2", "Var 3"),
)
  

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

Ответ №2:

Это можно сделать полностью в ggplot, но это довольно сложно. Фасеты — это действительно способ отображения дополнительных измерений одного и того же набора данных. Они не предназначены для произвольного сшивания разных графиков вместе, поэтому решение, полностью основанное на ggplot, требует манипулирования вашими данными и метками осей для создания видимости сшивания графиков вместе.

Сначала мы получаем уникальные уровни переменных barplot в виде символьных строк:

 levs    <- sort(unique(c(as.character(f$var_2), as.character(f$var_3))))
  

Теперь мы преобразуем множители в числа:

 f$var_2 <- as.numeric(factor(f$var_2, levs))   ceiling(max(f$var_1))   10
f$var_3 <- as.numeric(factor(f$var_3, levs))   ceiling(max(f$var_1))   10
  

Теперь мы создадим разрывы и метки, которые будем использовать для нашей оси x

 breaks  <- c(pretty(range(f$var_1)), sort(unique(c(f$var_2, f$var_3))))
labs    <- c(pretty(range(f$var_1)), levs)
  

Теперь мы можем безопасно поворачивать наш фрейм данных:

 f <- pivot_longer(f, cols = c("var_1", "var_2", "var_3")) 
  

Для нашего графика мы будем использовать соответствующие подмножества групп из фрейма данных для графика плотности и столбчатых графиков. Затем мы выполняем фасетирование с помощью свободных масштабов и помечаем ось x нашими предопределенными разрывами и метками:

 ggplot(f, aes(x = value))  
  geom_density(data = subset(f, name == "var_1"))  
  geom_bar(data = subset(f, name != "var_1"), aes(fill = name))  
  facet_wrap(cluster~name, ncol = 3, scales = "free")  
  scale_x_continuous(breaks = breaks, labels = labs)  
  scale_fill_manual(values = c("deepskyblue4", "gold"), guide = guide_none())
  

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