2015-10-21 8 views
9

Sto provando a mantenere lo "spazio vuoto" per i boxplot raggruppati a più livelli.ggplot2: forzare lo spazio per la categoria di secondo livello vuota

set.seed(42) 
n <- 100 
dat <- data.frame(x=runif(n), 
        cat1=sample(letters[1:4], size=n, replace=TRUE), 
        cat2=sample(LETTERS[1:3], size=n, replace=TRUE)) 
ggplot(dat, aes(cat1, x)) + geom_boxplot(aes(fill=cat2)) 

enter image description here

Se forzo uno dei gruppi da vuoto:

dat <- subset(dat, ! (cat1 == 'b' & cat2 == 'B')) 
table(dat$cat1, dat$cat2) 
##  
##  A B C 
## a 9 9 7 
## b 8 0 5 
## c 13 11 6 
## d 11 10 5 
ggplot(dat, aes(cat1, x)) + geom_boxplot(aes(fill=cat2)) 

enter image description here

Il secondo gruppo, "b", viene ora ampliato per riempire lo spazio . Quello che mi piace è:

enter image description here

SO 9818835 (forzando un livello di vuoto di apparire) funziona benissimo al livello superiore, ma non riesco a capire come farlo funzionare per un secondo livello di categorie. in scale_x_discrete(...), ho provato impostazione:

  • breaks=letters[1:4]
  • breaks=LETTERS[1:3]
  • breaks=list(letters[1:4], LETTERS[1:3]) (uno stab)
  • breaks=NULL
  • breaks=func dove func <- function(x, ...) { browser(); 1; } per risolvere; ha offerto solo letters[1:4] e non ha mai richiesto il secondo livello

L'utilizzo di interactions(letters[1:4], LETTERS[1:3]) non lascia ancora spazio vuoto. Ho provato una soluzione iniettando un valore fuori limite x e forzandolo dallo schermo con scale_y_continuous(limits), ma ggplot2 è troppo intelligente per me e colmerà di nuovo il buco.

Esistono soluzioni eleganti (ad es. "Corrette" nei meccanismi ggplot2)?

+0

Come elegante ne ha bisogno di essere? Basta impostare 'x' su zero per questi record sembra creare qualcosa che sembra abbastanza ragionevole. 'dat <- dat %>% mutate (x = ifelse (cat1 == 'b' & cat2 == 'B', 0, x))' – akhmed

+1

Ciò è elegante a livello di codice (e l'avevo già provato, senza 'scale_y_continuous (limits)' passo), ma sono un po 'ossessivo quando si tratta delle mie visualizzazioni: fisserò sempre la linea di distrazione nella parte inferiore della trama. – r2evans

+0

Inoltre c'è la differenza statistica tra "una linea significa nessun dato" e "una linea indica un singolo punto di dati di valore 0". – r2evans

risposta

7

Potrebbe coord_cartesian essere una soluzione che stai cercando?

Sarà ingrandire e non cercherà di "astuzia" i dati come scale_y_continuous

library(dplyr) 
library(ggplot2) 

set.seed(42) 
n <- 100 
dat <- data.frame(x=runif(n), 
        cat1=sample(letters[1:4], size=n, replace=TRUE), 
        cat2=sample(LETTERS[1:3], size=n, replace=TRUE)) 

LARGE_VALUE <- 2 

dat <- dat %>% 
    mutate(x = ifelse(cat1 == 'b' & cat2 == 'B', 
        LARGE_VALUE, 
        x)) 

ggplot(dat, aes(cat1, x)) + 
    geom_boxplot(aes(fill=cat2)) + 
    coord_cartesian(ylim = c(0,1)) 

enter image description here

+0

Sì, fa quello che mi serve. Sono un po 'sorpreso dal fatto che 'drop = FALSE' non faccia quello che penso che farebbe, ma poi ho di nuovo bisogno di lavorare di più per eliminare completamente' ggplot2'. Grazie. – r2evans

Problemi correlati