2012-07-20 8 views
22

Ho un dataframe che acquisisce diverse misure nel tempo che vorrei visualizzare una sfaccettatura 3x1. Tuttavia, ogni misura contiene diverse unità/scale che trarrebbero beneficio da trasformazioni personalizzate e schemi di etichettatura.Etichette per asse variabile formatter per facet in ggplot/R

Quindi, la mia domanda è: Se le unità e le scale sono diverse tra diversi aspetti, come posso specificare un formattatore personalizzato o una trasformazione (ad esempio, log10) su un particolare asse all'interno di un aspetto?

Per esempio, diciamo che ho i dati:

df = data.frame(dollars=10^rlnorm(50,0,1), counts=rpois(50, 100)) 
melted.df = melt(df, measure.var=c("dollars", "counts")) 

come si potrebbe andare su di creazione di una sfaccettatura 2x1 che mostra dollari e conta sopra l'indice con labels=dollars e scale_y_continuous(trans = "log10", ...) per i dati df$dollars?

Grazie!

+0

non facile, penso ... –

+0

Sì. Shucks. Ho appena trovato questo link in cui qualcuno ha riscontrato un problema simile: http://comments.gmane.org/gmane.comp.lang.r.ggplot2/4496. –

+0

Probabilmente è più facile fare due trame separate e organizzarle insieme. –

risposta

40

Come hai scoperto, non c'è una soluzione facile a questo, ma si presenta molto. Dal momento che questo tipo di cose viene chiesto così spesso, trovo utile spiegare perché questo è difficile, e suggerire una possibile soluzione.

La mia esperienza è stata che la gente viene a ggplot2 o reticolo grafica fondamentalmente fraintendere lo scopo della sfaccettatura (o trellising, in reticolo). Questa funzione è stata sviluppata con un'idea ben precisa in mente: la visualizzazione dei dati su più gruppi che condividono una scala comune. Deriva da qualcosa chiamato il principio dei piccoli multipli, sposato da Tufte e altri.

Posizionare pannelli uno accanto all'altro con scale molto diverse è qualcosa che gli esperti di visual design tenderanno ad evitare, perché può essere nel migliore dei casi fuorviante. (Non ti sto rimproverando qui, solo spiegando il fondamento logico ...)

Ma ovviamente, una volta che hai aperto questo fantastico strumento, non sai mai come lo useranno. Quindi viene allungato: le richieste arrivano per la capacità di consentire alle scale di variare in base al pannello e di impostare vari aspetti della trama separatamente per ciascun pannello. E così la sfaccettatura in ggplot2 è stata ampliata ben oltre il suo intento originario.

Una conseguenza di ciò è che alcune cose sono difficili da implementare semplicemente a causa dell'intento di progettazione originale della funzionalità. Questo è probabilmente uno di questi casi.

Ok, una spiegazione sufficiente. Ecco la mia soluzione.

Il trucco qui consiste nel riconoscere che si tratta di grafici che condividono una scala. Per me, questo significa che non dovresti nemmeno pensare di usare la sfaccettatura. Invece, fare ogni appezzamento a parte, e disporle insieme in una trama:

library(gridExtra) 

p1 <- ggplot(subset(melted.df,variable == 'dollars'), 
       aes(x = value)) + 
      facet_wrap(~variable) + 
      geom_density() + 
      scale_x_log10(labels = dollar_format()) 

p2 <- ggplot(subset(melted.df,variable == 'counts'), 
       aes(x = value)) + 
      facet_wrap(~variable) + 
      geom_density() 

grid.arrange(p1,p2) 

enter image description here

Ho appena intuito quello geom_* si voleva utilizzare, e sono sicuro che questo non è davvero quello che volevi tracciare, ma almeno illustra il principio.

+0

Grazie per la risposta perspicace! Comprendo perfettamente le implicazioni di allontanarsi dalle intenzioni progettuali originali per ggplot2. In pratica, ho due serie di dati in cui una segue una distribuzione normale mentre l'altra segue una distribuzione log-normale, quindi speravo di poter confrontare i dati visivamente normalizzati nel tempo. Avete qualche informazione su come allineare correttamente le aree del tracciato? Ho già incontrato la libreria 'ggExtra', che presumibilmente fornisce un supporto ad hoc per questo, ma apprezzerei qualsiasi direzione. –

+0

@StefanNovak Sono contento che sia stato utile! Voglio sottolineare ancora una volta che non stavo criticando le tue scelte progettuali. Un principio delle domande SO è che "vivono per sempre" e quindi dovrebbero servire a servire più del semplice richiedente originale. Come ho detto, questo viene ripetuto più e più volte, quindi la mia spiegazione è stata più diretta ai lettori futuri di quanto non lo siate specificamente. – joran

+1

@StefanNovak Bene, il modo hacky per farlo è quello di regolare le etichette di graduazione degli assi in modo che abbiano lo stesso numero di cifre, anche se ciò significa riempire le etichette con spazi vuoti. Sono sicuro che sia stato già chiesto prima ... Vedrò se riesco a trovare qualcosa di relavent. – joran