2013-03-12 12 views
14

Sto provando a disegnare una casella e il diagramma del baffo in R. Il mio codice è di sotto. Al momento, poiché ho solo dati per due mesi in uno dei due siti, le barre sono più larghe per quel sito (perché il terzo livello del mese è caduto).Includere lo spazio per il livello di fattore mancante utilizzato nell'estetica di riempimento in geom_boxplot

Invece, vorrei lo stesso modello di box per il sito A come per il sito B (cioè con spazio per una casella vuota sul lato destro). Posso farlo facilmente con drop=TRUE quando ho solo un fattore ma non riesco a farlo con il fattore "riempimento".

Month=rep(c(rep(c("Jan","Feb"),2),"Mar"),10) 
Site=rep(c(rep(c("A","B"),each=2),"B"),10) 
factor(Month) 
factor(Site) 
set.seed(1114) 
Height=rnorm(50) 
Data=data.frame(Month,Site,Height) 
plot = ggplot(Data, aes(Site, Height)) + 
     geom_boxplot(aes(fill=Month, drop=TRUE), na.rm=FALSE) 
plot 
+0

+1 per una bella autosufficiente esempio riproducibile. Benvenuti in SO. –

+0

possibile duplicato di [Larghezza coerente per geom \ _bar in caso di dati mancanti] (http://stackoverflow.com/questions/11020437/consistent-width-for-geom-bar-in-the-event-of-missing -data) –

+0

@BrianDiggs Non sono sicuro che questa soluzione funzioni con geom_boxplot() –

risposta

12

Un modo per ottenere l'aspetto desiderato è modificare i dati prodotti durante la stampa.

Prima di tutto, salvare il grafico come oggetto e quindi utilizzare ggplot_build() per salvare tutte le parti dei dati di stampa come oggetto.

p<-ggplot(Data, aes(Site, Height,fill=Month)) + geom_boxplot() 
dd<-ggplot_build(p) 

I dati dell'elemento di elenco contengono tutte le informazioni utilizzate per la stampa.

dd$data 

[[1]] 
    fill  ymin  lower  middle  upper  ymax outliers notchupper notchlower x PANEL 
1 #F8766D -1.136265 -0.2639268 0.1978071 0.5318349 0.9815675   0.5954014 -0.1997872 0.75  1 
2 #00BA38 -1.264659 -0.6113666 0.3190873 0.7915052 1.0778202   1.0200180 -0.3818434 1.00  1 
3 #F8766D -1.329028 -0.4334205 0.3047065 1.0743448 1.5257798   1.0580462 -0.4486332 1.75  1 
4 #00BA38 -1.137494 -0.7034188 -0.4466927 -0.1989093 0.1859752 -1.759846 -0.1946196 -0.6987658 2.00  1 
5 #619CFF -2.344163 -1.2108919 -0.5457815 0.8047203 2.3773189   0.4612987 -1.5528617 2.25  1 
    group weight ymin_final ymax_final xmin xmax 
1  1  1 -1.136265 0.9815675 0.625 0.875 
2  2  1 -1.264659 1.0778202 0.875 1.125 
3  3  1 -1.329028 1.5257798 1.625 1.875 
4  4  1 -1.759846 0.1859752 1.875 2.125 
5  5  1 -2.344163 2.3773189 2.125 2.375 

siete interessati a x, xmax e xmin valori. Le prime due righe corrispondono al livello A. Quei valori dovrebbero essere cambiati.

dd$data[[1]]$x[1:2]<-c(0.75,1) 
dd$data[[1]]$xmax[1:2]<-c(0.875,1.125) 
dd$data[[1]]$xmin[1:2]<-c(0.625,0.875) 

Ora usano ggplot_gtable() e grid.draw() per tracciare i dati modificati.

library(grid) 
grid.draw(ggplot_gtable(dd)) 

enter image description here

+0

Grazie mille per questa risposta. Mi piace usare 'ggplot_build' per estrarre i dati dal grafico e' ggplot_gtable' e 'grid.draw' per tracciare i dati modificati. Nota: 'plot' funziona pure, combinato con' ggplot_gtable' per ri-tracciare i dati –

+0

'gtable ::: plot.gtable' fa qualcosa di diverso, vuoi usare 'grid.draw' – baptiste

17

Ecco una soluzione, che si basa sulla creazione di dati falsi:

In primo luogo, una nuova riga viene aggiunto al frame di dati. Contiene un punto dati per la combinazione non esistente di livelli di fattore (Mar e A). Il valore di Height deve essere al di fuori dell'intervallo dei dati reali Height.

Data2 <- rbind(Data, data.frame(Month = "Mar", Site = "A", Height = 5)) 

Quindi, è possibile generare il grafico. Poiché i dati falsi non dovrebbero essere visibili, i limiti dell'asse y devono essere modificati con coord_cartesian e il range dei dati originali Height.

library(ggplot2) 
ggplot(Data2, aes(Site, Height)) + 
    geom_boxplot(aes(fill = Month)) + 
    coord_cartesian(ylim = range(Data$Height) + c(-.25, .25)) 

enter image description here

+0

(+1) per un semplice uso di dati falsi. –

+0

Grazie mille per questo modo piuttosto ingegnoso per risolvere questo. –

Problemi correlati