2010-09-23 11 views
203

Una domanda molto newbish, ma dire che ho dati in questo modo:Tracciando due variabili come linee che utilizzano ggplot2 sullo stesso grafico

test_data <- 
    data.frame(
    var0 = 100 + c(0, cumsum(runif(49, -20, 20))), 
    var1 = 150 + c(0, cumsum(runif(49, -10, 10))), 
    date = seq(as.Date("2002-01-01"), by="1 month", length.out=100) 
) 

Come posso tracciare entrambe le serie di tempo var0 e var1 sullo stesso grafico, con date sull'asse x, utilizzando ggplot2? Punti bonus se fai var0 e var1 colori diversi e puoi includere una legenda!

Sono sicuro che è molto semplice, ma non riesco a trovare alcun esempio.

risposta

259

Per un piccolo numero di variabili, è possibile utilizzare costruire la trama manualmente da soli:

ggplot(test_data, aes(date)) + 
    geom_line(aes(y = var0, colour = "var0")) + 
    geom_line(aes(y = var1, colour = "var1")) 
+1

bel esempio, ma come personalizzare i miei colori (Per esempio nero e arancione) ?, perché sembra che tu stia usando 'color =' come nome della variabile. –

+8

Utilizzare una scala .... – hadley

+3

'+ scale_colour_manual (valori = c (" nero "," arancione "))' –

12

Utilizzando i dati:

test_data <- data.frame(
var0 = 100 + c(0, cumsum(runif(49, -20, 20))), 
var1 = 150 + c(0, cumsum(runif(49, -10, 10))), 
Dates = seq.Date(as.Date("2002-01-01"), by="1 month", length.out=100)) 

creo una versione impilata che è ciò che ggplot() piacerebbe lavorare con:

stacked <- with(test_data, 
       data.frame(value = c(var0, var1), 
          variable = factor(rep(c("Var0","Var1"), 
               each = NROW(test_data))), 
          Dates = rep(Dates, 2))) 

In questo caso la produzione di stacked era abbastanza facile come abbiamo solo dovuto fare un paio di manipolazioni, ma reshape() e reshape e reshape2 potrebbero essere utili se si dispone di un set di dati reali più complesso da manipolare.

Una volta che i dati sono in questa forma impilato, richiede solo un semplice ggplot() chiamata a produrre la trama si voleva con tutti gli extra (uno dei motivi per cui di livello superiore pacchetti plottaggio come lattice e ggplot2 sono così utili):

require(ggplot2) 
p <- ggplot(stacked, aes(Dates, value, colour = variable)) 
p + geom_line() 

lascio a voi per riordinare le etichette degli assi, titolo di legenda ecc

HTH

+1

I pensi avere un parental malriposto nel tuo codice lassù. Penso che questo sia quello che stai cercando: impilato <- con (test_data, data.frame (valore = c (var0, var1), variabile = fattore (rep (c ("Var0", "Var1"))), ciascuno = NROW (test_data), Date = rep (data, 2))). Inoltre, qual è lo scopo della colonna "ciascuno"? E questo non è solo un modo più contorto e meno efficace per sciogliere i dati come mostrato da rcs? Immagino di poter immaginare un'istanza in cui lo scioglimento non avrebbe portato a termine il lavoro, ma è quasi certamente lo strumento giusto per questo lavoro a meno che mi manchi qualcosa? – Chase

+1

@chase, mi dispiace, questo è Emacs ESS che ha sbagliato il rientro. ognuno è un argomento per 'rep()', quindi stiamo solo ottenendo 3 colonne in 'stacked'. Modificherò il codice per rendere più chiaro il rientro. –

+1

@chase; il tuo commento su 'melt()' è ben preso, e noto che il pacchetto di rimodella [2] sarebbe utile qui. Non sono così familiare con reshape2 e per una semplice manipolazione che lo fa a mano è più complesso di una chiamata a 'melt()', era meno sforzo in quanto non avevo bisogno di leggere come usare 'melt() '. E rcs si intrufolò nella sua risposta mentre stavo producendo il mio; quando ho iniziato la risposta non c'erano state risposte. più di un modo per scuoiare un gatto - come si suol dire! ;-) –

272

L'approccio generale è quello di convertire i dati in formato lungo (usando melt() dalla confezione reshape o reshape2) o gather() dal pacchetto tidyr:

library("reshape2") 
library("ggplot2") 

test_data_long <- melt(test_data, id="date") # convert to long format 

ggplot(data=test_data_long, 
     aes(x=date, y=value, colour=variable)) + 
     geom_line() 

ggplot2 output

+4

Puoi anche usare la funzione 'gather()' del pacchetto 'tidyr' per fondere i dati:' gather (test_data, variable, value, -date) ' – janosdivenyi

12

Hai bisogno che i dati siano in formato "alto" anziché "largo" per ggplot2. "wide" significa avere un'osservazione per riga con ogni variabile come una colonna diversa (come hai ora). Devi convertirlo in un formato "alto" in cui hai una colonna che ti dice il nome della variabile e un'altra colonna che ti dice il valore della variabile. Il processo di passaggio da largo ad alto è solitamente chiamato "fusione".È possibile utilizzare tidyr::gather per fondere la cornice di dati:

library(ggplot2) 
library(tidyr) 

test_data <- 
    data.frame(
    var0 = 100 + c(0, cumsum(runif(49, -20, 20))), 
    var1 = 150 + c(0, cumsum(runif(49, -10, 10))), 
    date = seq(as.Date("2002-01-01"), by="1 month", length.out=100) 
) 
test_data %>% 
    gather(key,value, var0, var1) %>% 
    ggplot(aes(x=date, y=value, colour=key)) + 
    geom_line() 

multiple series ggplot2

tanto per essere chiari il data che ggplot sta consumando dopo tubazioni tramite gather assomiglia a questo:

date  key  value 
2002-01-01 var0 100.00000 
2002-02-01 var0 115.16388 
... 
2007-11-01 var1 114.86302 
2007-12-01 var1 119.30996 
Problemi correlati