Utilizzo di ggplot2 e facet_grid per variabili continue e categoriali insieme (R)

Aug 23 2020

Sto cercando di creare una serie di grafici come questa:

Ho alcuni dati misti categoriali e continui. Sono in grado di realizzare questa serie di grafici quando ci sono solo variabili categoriali o quando ci sono solo variabili continue. Ma non sono in grado di produrre questa serie di grafici quando ci sono entrambi i tipi di variabili.

Ho creato alcuni dati di seguito. C'è un modo per eseguire il debug di questo codice in modo che produca una serie di grafici?

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")

Quando ho solo variabili categoriali, il seguente codice funziona:

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")

Risposte

AllanCameron Aug 23 2020 at 17:18

Questo è possibile farlo interamente all'interno di ggplot, ma è piuttosto complicato. Le sfaccettature sono davvero un modo per mostrare dimensioni extra dello stesso set di dati. Non intendono essere un modo per unire arbitrariamente diversi grafici, quindi una soluzione interamente basata su ggplot richiede la manipolazione dei dati e delle etichette degli assi per produrre l' aspetto di unire grafici insieme.

Innanzitutto, otteniamo i livelli univoci delle variabili del grafico a barre come stringhe di caratteri:

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

Ora convertiamo i fattori in numeri:

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

Costruiremo ora le interruzioni e le etichette che useremo per il nostro asse 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)

Ora possiamo ruotare in sicurezza il nostro data frame:

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

Per il nostro grafico, utilizzeremo gruppi opportunamente suddivisi dal frame di dati per il grafico della densità e i grafici a barre. Quindi sfaccettiamo con scale libere ed etichettiamo l'asse x con le nostre interruzioni ed etichette predefinite:

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())

1 DavidGibson Aug 23 2020 at 13:23

Non credo ggplot in grado di gestire sia le variabili continue e categoriali nella yo x estetica . Ma c'è anche un errore quando li mescoli nel file pivot_longer().

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

La mia raccomandazione sarebbe quella di creare grafici separati per ogni metrica e quindi combinare i grafici. Questo ti darà un maggiore controllo su ogni trama. Ecco un esempio che utilizza ggmatrix () di GGally . Sono sicuro che questo è possibile anche con 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"),
)