2013-05-23 15 views
10

Sto facendo un diagramma a scatola in cui x e fill vengono mappati a variabili diverse, un po 'come questo:forza grafici a scatole da geom_boxplot a larghezza costante

ggplot(mpg, aes(x=as.factor(cyl), y=cty, fill=as.factor(drv))) + 
    geom_boxplot() 

enter image description here

Come nell'esempio precedente, le larghezze delle mie scatole escono in modo diverso a diversi valori x, perché non ho tutte le combinazioni possibili di valori x e fill, quindi.

Vorrei che tutte le caselle abbiano la stessa larghezza. Questo può essere fatto (idealmente senza manipolare il data frame sottostante, perché temo che l'aggiunta di dati falsi possa causare confusione durante ulteriori analisi)?

Il mio primo pensiero è stato

+ geom_boxplot(width=0.5) 

, ma questo non aiuta; regola la larghezza del set completo di grafici a scatole per un determinato livello di fattore x.

This postquasi sembra rilevante, ma non vedo come applicarlo alla mia situazione. L'utilizzo di + scale_fill_discrete(drop=FALSE) non sembra modificare le larghezze delle barre.

risposta

1

Il problema è dovuto al fatto che alcune celle di combinazioni di fattori non sono presenti. Il numero di punti di dati per tutte le combinazioni dei livelli di cyl e drv può essere controllato tramite xtabs:

tab <- xtabs(~ drv + cyl, mpg) 

tab 

# cyl 
# drv 4 5 6 8 
# 4 23 0 32 48 
# f 58 4 43 1 
# r 0 0 4 21 

Ci sono tre celle vuote. Aggiungerò dati falsi per ignorare i problemi di visualizzazione.

Controllare il range della variabile dipendente (asse y). I dati falsi devono essere fuori da questo intervallo.

range(mpg$cty) 
# [1] 9 35 

Creare un sottoinsieme di mpg con i dati necessari per il terreno:

tmp <- mpg[c("cyl", "drv", "cty")] 

creare un indice per le celle vuote:

idx <- which(tab == 0, arr.ind = TRUE) 

idx 

# row col 
# r 3 1 
# 4 1 2 
# r 3 2 

creare tre linee falsi (con -1 come valore per cty):

fakeLines <- apply(idx, 1, 
        function(x) 
        setNames(data.frame(as.integer(dimnames(tab)[[2]][x[2]]), 
             dimnames(tab)[[1]][x[1]], 
             -1), 
           names(tmp))) 

fakeLines 

# $r 
# cyl drv cty 
# 1 4 r -1 
# 
# $`4` 
# cyl drv cty 
# 1 5 4 -1 
# 
# $r 
# cyl drv cty 
# 1 5 r -1 

Aggiungere le righe ai dati esistenti:

tmp2 <- rbind(tmp, do.call(rbind, fakeLines)) 

Trama:

library(ggplot2) 
ggplot(tmp2, aes(x = as.factor(cyl), y = cty, fill = as.factor(drv))) + 
    geom_boxplot() + 
    coord_cartesian(ylim = c(min(tmp$cty - 3), max(tmp$cty) + 3)) 
    # The axis limits have to be changed to suppress displaying the fake data. 

enter image description here

Problemi correlati