2015-10-21 6 views
9

Ich versuche, "leeren Raum" für Multi-Level-gruppierten Boxplots zu halten.ggplot2: Erzwingt Platz für leere Second-Level-Kategorie

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

Wenn ich zwingen eine der Gruppen leer zu sein:

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

Die zweite Gruppe, "b", erweitert wird nun um den Raum zu füllen, . Was ich möchte, ist:

enter image description here

SO 9818835 (zwingt eine leere Ebene zu erscheinen) funktioniert auf der obersten Ebene, aber ich kann nicht herausfinden, wie es für eine zweite Ebene zur Arbeit kommen von Kategorien. in scale_x_discrete(...) habe ich versucht Rahmen:

  • breaks=letters[1:4]
  • breaks=LETTERS[1:3]
  • breaks=list(letters[1:4], LETTERS[1:3]) (a stab)
  • breaks=NULL
  • breaks=func wo func <- function(x, ...) { browser(); 1; } um zu beheben; es bot nur letters[1:4] und nie für die zweite Ebene aufgefordert

Mit interactions(letters[1:4], LETTERS[1:3]) noch nicht leeren Raum nicht verlässt. Ich versuchte einen Workaround, indem ich einen Out-of-Bounds x Wert einspritze und ihn vom Bildschirm mit scale_y_continuous(limits) erzwingt, aber ggplot2 ist zu klug für mich und schließt die Lücke wieder.

Gibt es elegante (d. H. "Korrekte" ggplot2 Mechanismen) Lösungen?

+0

Wie elegant braucht es zu sein? Wenn man 'x' für diese Datensätze auf Null setzt, scheint etwas zu entstehen, das ziemlich vernünftig aussieht. 'dat <- dat %>% mutiere (x = ifelse (cat1 == 'b' & cat2 == 'B', 0, x))' – akhmed

+1

Das ist programmatisch elegant (und ich hatte es bereits versucht, ohne die 'scale_y_continuous (limits)') Schritt), aber ich bin ein wenig OCD, wenn es um meine Visualisierungen geht: Ich werde immer auf die störende Linie am Ende der Handlung starren. – r2evans

+0

Plus gibt es den statistischen Unterschied zwischen "eine Linie bedeutet keine Daten" und "eine Linie zeigt einen einzelnen Datenpunkt des Wertes 0 an". – r2evans

Antwort

7

Konnte coord_cartesian eine Lösung sein, die Sie suchen?

Es wird die Ansicht vergrößert und wird nicht versuchen, „austricksen“ die Daten wie 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

Yup, das tut, was ich brauche. Ich bin ein wenig überrascht, dass 'drop = FALSE' nicht das tut, was ich denke, aber dann muss ich mehr arbeiten, um' ggplot2' voll zu wachsen. Vielen Dank. – r2evans