2010-09-23 19 views
203

Une question très newbish, mais dire que j'ai données comme ceci:Traçage deux variables comme des lignes en utilisant ggplot2 sur le même graphique

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) 
) 

Comment puis-je tracer les deux séries chronologiques var0 et var1 sur le même graphique, avec date sur l'axe des x, en utilisant ggplot2? Les points bonus si vous faites var0 et var1 différentes couleurs, et peuvent inclure une légende! Je suis sûr que c'est très simple, mais je ne trouve pas d'exemples là-bas.

Répondre

259

Pour un petit nombre de variables, vous pouvez utiliser construire l'intrigue vous-même manuellement:

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

bel exemple, mais comment personnaliser mes propres couleurs (Par exemple, noir et orange)?, Car il semble que vous utilisiez 'color =' comme nom de variable. –

+8

Utiliser une échelle .... – hadley

+3

'+ scale_colour_manual (valeurs = c (" noir "," orange "))' –

12

Utilisation de vos données:

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)) 

Je crée une version empilée qui est ce que ggplot() voudrait travailler avec:

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

Dans ce cas, la production stacked était assez facile car nous ne devions faire quelques manipulations, mais reshape() et les reshape et reshape2 pourraient être utiles si vous avez un ensemble de données réel plus complexe à manipuler.

Une fois que les données sont dans cette forme empilée, il ne nécessite qu'un simple appel ggplot() pour produire le tracé que vous vouliez avec tous les extras (une des raisons pour lesquelles un paquet de traçage de niveau supérieur comme lattice et ggplot2 sont si utiles):

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

Je vais laisser à vous de ranger les étiquettes de l'axe, le titre de légende, etc.

HTH

+1

Je pense que vous avoir une parenthèse égarée dans votre code là-haut. Je pense que c'est ce que vous êtes après: empilé <- avec (test_data, data.frame (valeur = c (var0, var1), variable = facteur (rep (c ("Var0", "Var1"))), chacun = NROW (test_data), Dates = rep (date, 2))). Aussi, quel est le but de la colonne "each"? Et n'est-ce pas simplement une manière plus compliquée et moins efficace de faire fondre les données comme indiqué par rcs? Je suppose que je pourrais imaginer un cas où la fonte ne ferait pas le travail, mais c'est presque certainement le bon outil pour ce travail à moins que je ne manque quelque chose? – Chase

+1

@chase, désolé, c'est Emacs ESS obtenant l'indentation incorrecte. each est un argument de 'rep()', donc nous n'obtenons vraiment que 3 cols dans 'stacked'. Je vais modifier le code pour rendre le retrait plus clair. –

+1

@chase; votre commentaire sur 'melt()' est bien pris, et je note que le paquet reshape [2] serait utile ici. Je ne suis pas familier avec reshape2 et pour une manipulation aussi simple, le faire à la main est plus complexe qu'un appel à 'melt()', c'était moins d'effort car je n'avais pas besoin de lire comment utiliser 'melt() '. Et le RC s'est faufilé dans sa réponse pendant que je produisais le mien; quand j'ai commencé la réponse, il n'y avait pas de réponses. plus d'une façon de peler un chat - comme on dit! ;-) –

272

L'approche générale est de convertir les données au format long (en utilisant melt() du paquet reshape ou reshape2) ou gather() de l'emballage 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

Vous pouvez également utiliser la fonction 'gather()' du paquetage 'tidyr' pour faire fondre les données:' gather (test_data, variable, value, -date) ' – janosdivenyi

12

Vous avez besoin que les données soient au format "grand" au lieu de "large" pour ggplot2. "large" signifie avoir une observation par ligne avec chaque variable comme une colonne différente (comme vous avez maintenant). Vous devez le convertir dans un format "grand" où vous avez une colonne qui vous indique le nom de la variable et une autre colonne qui vous indique la valeur de la variable. Le processus de passage de large à grand est généralement appelé "fusion".Vous pouvez utiliser tidyr::gather pour faire fondre votre bloc de données:

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

Pour être clair la data que ggplot consomme après la tuyauterie par gather ressemble à ceci:

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