web-dev-qa-db-fra.com

Tracer deux variables sous forme de lignes à l'aide de ggplot2 sur le même graphique

Une question très newbish, mais disons que j'ai des données comme celle-ci:

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 tracer les deux séries temporelles var0 et var1 sur le même graphique, avec date sur l'axe des x, à l'aide de ggplot2? Points bonus si vous faites var0 et var1 couleurs différentes, et pouvez inclure une légende!

Je suis sûr que c'est très simple, mais je ne trouve aucun exemple là-bas.

282
fmark

Pour un petit nombre de variables, vous pouvez créer le tracé manuellement vous-même:

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

L’approche générale consiste à convertir les données au format long (en utilisant melt() à partir du package reshape ou reshape2) ou gather() à partir du package 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

342
rcs

Vous avez besoin que les données soient au format "grand" au lieu de "grand" pour ggplot2. "large" signifie avoir une observation par ligne avec chaque variable dans une colonne différente (comme vous l'avez maintenant). Vous devez le convertir au format "grand" dans lequel 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 fusionner votre trame 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 l'avoir acheminée via 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
31
ecerulm

En utilisant 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 sur laquelle ggplot() aimerait travailler:

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, produire stacked était assez facile car nous n’avions que quelques manipulations à faire, mais reshape() et les reshape et reshape2 pourraient être utiles si vous avez plus de possibilités. ensemble de données réelles complexes à manipuler.

Une fois que les données sont dans cette forme empilée, il suffit d’un simple appel de ggplot() pour générer le tracé souhaité avec tous les extras (une des raisons pour lesquelles les packages de traçage de niveau supérieur tels que lattice et ggplot2 sont si utiles):

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

Je vous laisse le soin de ranger les étiquettes d'axe, le titre de la légende, etc.

HTH

13
Gavin Simpson

Je suis également nouveau dans R, mais en essayant de comprendre le fonctionnement de ggplot, je pense avoir une autre façon de le faire. Je ne partage probablement que la solution parfaite, mais bien quelques points de vue différents.

Je sais que ggplot est conçu pour mieux fonctionner avec les images, mais il peut également être utile de savoir que vous pouvez tracer directement deux vecteurs sans utiliser d’image.

Chargement des données. La longueur du vecteur de date d'origine est 100 alors que var0 et var1 ont une longueur de 50, je ne trace que les données disponibles (les 50 premières dates).

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

Traçage

ggplot() + geom_line(aes(x=date,y=var0),color='red') + 
           geom_line(aes(x=date,y=var1),color='blue') + 
           ylab('Values')+xlab('date')

enter image description here

Cependant, je n'ai pas pu ajouter une légende correcte en utilisant ce format. Est-ce que quelqu'un sait comment?

4
Papalagui