Zeichnen von zwei Variablen als Linien mit ggplot2 im selben Diagramm


305

Eine sehr neue Frage, aber sagen Sie, ich habe Daten wie diese:

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

Wie kann ich sowohl Zeitreihen var0als auch var1auf demselben Diagramm mit dateauf der x-Achse zeichnen ggplot2? Bonuspunkte, wenn Sie var0und var1verschiedene Farben machen, und können eine Legende enthalten!

Ich bin mir sicher, dass dies sehr einfach ist, aber ich kann da draußen keine Beispiele finden.

Antworten:


373

Für eine kleine Anzahl von Variablen können Sie das Diagramm manuell selbst erstellen:

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

3
schönes Beispiel, aber wie kann ich meine eigenen Farben anpassen (zB Schwarz und Orange)?, weil es scheint, dass Sie colour=als Variablenname verwenden.
Darwin PC

1
auch colour='var_names'wie von hadley angegeben funktioniert gut. aber @DaveX - wäre spezifischer, wenn man bestimmte Farben auswählen möchte, anstatt automatisch von der Funktion ausgewählte Farben.
I_m_LeMarque

Wie kann ich eine Legende hinzufügen?
user1700890

361

Der allgemeine Ansatz besteht darin, die Daten in ein Langformat (unter Verwendung melt()von Paket reshapeoder reshape2) oder gather()/ pivot_longer()von tidyrPaket zu konvertieren :

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 Ausgabe

Siehe auch diese Frage zum Umformen von Daten von breit nach lang.


8
Sie können auch die gather()Funktion des tidyrPakets verwenden, um die Daten zu schmelzen:gather(test_data, variable, value, -date)
janosdivenyi

33

Sie müssen die Daten für "ggplot2" im Format "groß" anstelle von "breit" haben. "breit" bedeutet, eine Beobachtung pro Zeile mit jeder Variablen als einer anderen Spalte zu haben (wie Sie es jetzt getan haben). Sie müssen es in ein "hohes" Format konvertieren, in dem Sie eine Spalte mit dem Namen der Variablen und eine weitere Spalte mit dem Wert der Variablen haben. Der Übergang von breit nach hoch wird üblicherweise als "Schmelzen" bezeichnet. Sie können verwenden tidyr::gather, um Ihren Datenrahmen zu schmelzen:

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

mehrere Serien ggplot2

Nur um klar zu sein, datadass der ggplotVerbrauch nach dem Weiterleiten gatherwie folgt aussieht:

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

13

Verwenden Sie Ihre Daten:

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

Ich erstelle eine gestapelte Version, mit der ich arbeiten ggplot()möchte:

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 diesem Fall war das Produzieren stackedrecht einfach, da wir nur ein paar Manipulationen durchführen mussten, aber reshape()das reshapeund reshape2könnte nützlich sein, wenn Sie einen komplexeren realen Datensatz zum Manipulieren haben.

Sobald die Daten in dieser gestapelten Form vorliegen, ist nur ein einfacher ggplot()Aufruf erforderlich , um das gewünschte Diagramm mit allen Extras zu erstellen (ein Grund, warum übergeordnete Diagrammpakete so nützlich sind latticeund ggplot2sind):

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

Ich überlasse es Ihnen, die Achsenbeschriftungen, den Legendentitel usw. aufzuräumen.

HTH


1
Ich denke, Sie haben dort oben einen verlegten Parens in Ihrem Code. Ich denke, das ist es, wonach Sie suchen: gestapelt <- mit (test_data, data.frame (Wert = c (var0, var1), Variable = Faktor (rep (c ("Var0", "Var1"))), jeweils = NROW (test_data), Dates = rep (Datum, 2))). Was ist auch der Zweck der Spalte "jeweils"? Und ist dies nicht nur eine kompliziertere und weniger effiziente Methode, um die Daten zu schmelzen, wie von rcs gezeigt? Ich denke, ich könnte mir einen Fall vorstellen, in dem Schmelze den Job nicht erledigen würde, aber es ist mit ziemlicher Sicherheit das richtige Werkzeug für diesen Job, wenn mir nichts fehlt?
Chase

1
@chase, sorry, das ist Emacs ESS, das den Einzug falsch macht. Jedes ist ein Argument dafür rep(), also bekommen wir wirklich nur 3 Spalten rein stacked. Ich werde den Code bearbeiten, um den Einzug klarer zu machen.
Gavin Simpson

1
@Verfolgungsjagd; Ihr Kommentar zu melt()ist gut aufgenommen, und ich stelle fest, dass das Paket umformen [2] hier nützlich wäre. Ich bin mit reshape2 nicht so vertraut und für eine so einfache Manipulation von Hand ist es komplexer als ein Aufruf melt(), es war weniger Aufwand, da ich nicht lesen musste, wie man es benutzt melt(). Und rcs schlich sich mit seiner Antwort ein, während ich meine produzierte; Als ich mit der Antwort anfing, gab es keine Antworten. mehr als eine Möglichkeit, eine Katze zu häuten - wie sie sagen! ;-)
Gavin Simpson

7

Ich bin auch neu in R, aber ich versuche zu verstehen, wie ggplot funktioniert. Ich glaube, ich bekomme einen anderen Weg, es zu tun. Ich teile nur wahrscheinlich nicht als vollständige perfekte Lösung, sondern um einige verschiedene Sichtweisen hinzuzufügen.

Ich weiß, dass ggplot besser für die Arbeit mit Datenrahmen geeignet ist, aber manchmal kann es auch nützlich sein zu wissen, dass Sie zwei Vektoren direkt zeichnen können, ohne einen Datenrahmen zu verwenden.

Daten werden geladen. Die ursprüngliche Länge des Datumsvektors beträgt 100, während var0 und var1 die Länge 50 haben, sodass ich nur die verfügbaren Daten (die ersten 50 Daten) zeichne.

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)    

Plotten

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

Geben Sie hier die Bildbeschreibung ein

In diesem Format konnte ich jedoch keine korrekte Legende hinzufügen. Weiß jemand wie?


1
Dies fügt eine Legende hinzu ggplot() + geom_line(aes(x=date,y=var0, group=1, colour = 'red')) + geom_line(aes(x=date,y=var1, group = 2, colour = 'blue')) + ylab('Values')+xlab('date')
Flurbius
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.