So zeichnen Sie 20 Jahre tägliche Daten in Zeitreihen auf

9

Ich habe den folgenden Datensatz: https://dl.dropbox.com/u/22681355/ORACLE.csv und möchte die täglichen Änderungen in "Öffnen" nach "Datum" darstellen, also habe ich Folgendes getan:

oracle <- read.csv(file="http://dl.dropbox.com/u/22681355/ORACLE.csv", header=TRUE)
plot(oracle$Date, oracle$Open, type="l")

und ich bekomme folgendes:

Geben Sie hier die Bildbeschreibung ein

Dies ist offensichtlich nicht die schönste Darstellung aller Zeiten. Ich frage mich also, welche Methode für die Darstellung derart detaillierter Daten die richtige ist.

dbr
quelle
1
Die Handlung ist eigentlich nicht so schlecht ... aber wie man sie verbessert, hängt davon ab, was Sie hervorheben möchten. Möchten Sie nur wöchentliche Daten zeichnen? Möchten Sie eine glatte Linie hinzufügen? Sie sollten natürlich die Beschriftungen der x-Achse ändern ...
Peter Flom - Monica wieder herstellen
Ja, ich hätte gerne glatte Linien, wie zum Beispiel: dl.dropbox.com/u/22681355/Untitled.tiff , es ist in Ordnung , wenn die Skalierung in Jahren ist, aber die glatte Linie wäre wichtig. Ich habe versucht, den Typ in "l" zu ändern, aber es hat nichts wirklich getan.
dbr
In Reiner Weise ist es, glatte Linien hinzuzufügen loess. Ich bin auf dem Weg nach draußen, aber versuche es mit Löss in R und wenn du Probleme hast, bearbeite deinen Beitrag und jemand wird dir sicherlich helfen können. Es gibt auch andere Glättungsmethoden, aber ich denke, Löss ist eine gute Standardeinstellung.
Peter Flom - Monica wieder einsetzen

Antworten:

8

Das Problem mit Ihren Daten ist nicht, dass sie extrem detailliert sind: Sie haben am Wochenende keine Werte, deshalb werden sie mit Lücken dargestellt. Es gibt zwei Möglichkeiten, damit umzugehen:

  1. Entweder versuchen ungefähre Werte in den Wochenenden mit einigen Glättungsverfahren zu erraten ( smooth.spline, loessusw.). Der Code der einfachen Interpolation ist unten. In diesem Fall führen Sie jedoch etwas "Unnatürliches" und Künstliches in die Daten ein. Deshalb bevorzuge ich die zweite Option.
currentDate <- min(as.Date(oracle$Date))
dates <- c(currentDate)
openValues <- c(oracle$Open[5045])
i <- 5044
while (i > 0) {
  currentDate <- currentDate + 1;
  dates <- c(dates, currentDate)
  if (currentDate == as.Date(oracle$Date[i])) {
        # just copy value and move
        openValues <- c(openValues, oracle$Open[i])
        i <- i-1
      } else {
        # interpolate value
        openValues <- c(openValues, mean(oracle$Open[i:i-1]))
  }
}
plot(dates, openValues, type="l")
  1. Sie können von der täglichen zur wöchentlichen Basis wechseln und nur (zum Beispiel) fünf aufeinanderfolgende Punkte mitteln, die einer Woche entsprechen (in diesem Fall "töten" Sie einige Informationen). Nur ein kurzes Beispiel dafür wäre
openValues = c(mean(oracle$Open[1:5]));
dates = c(as.Date(oracle$Date[1]));
for (i in seq(6,5045,5)) {
  openValues = c(openValues, mean(oracle$Open[i:i+5]));
      dates = c(dates, as.Date(oracle$Date[i]));
}
plot(dates, openValues, type="l")

Hoffe es wird helfen.

Dmitry Laptev
quelle
1
danke, das ist wirklich hilfreich. Das Problem ist, dass, da es sich um Bestandsdaten handelt, ein Wechsel von der täglichen zur wöchentlichen Basis definitiv einige wichtige Daten "töten" könnte. Gibt es eine Möglichkeit, glatte Linien für die Tage und leere Räume für die Wochenenden zu haben?
dbr
Ok, wenn es für Sie wichtig ist, nicht zu mitteln, habe ich die Antwort aktualisiert und den Beispielcode für die Interpolation der Wochenenden bereitgestellt.
Dmitry Laptev
@dbr Übrigens, wenn Sie sich bei der Interpolation auf R verlassen möchten, wäre das extrem einfach:plot(as.Date(oracle$Date), oracle$Open, type='l')
Dmitry Laptev
1
Und für den Fall, dass Sie nur am Wochenende Lücken wollen, ersetzen Sie die Zeile openValues <- c(openValues, mean(oracle$Open[i:i-1]))in der ersten Methode durchopenValues <- c(openValues, NA)
Dmitry Laptev
9

Da das Problem in vielen statistischen Softwareumgebungen häufig vorkommt, wollen wir es hier auf Cross Validated diskutieren, anstatt es in ein R-spezifisches Forum (wie StackOverflow) zu migrieren.

Das eigentliche Problem ist, dass Datees als Faktor - eine diskrete Variable - behandelt wird und die Leitungen daher nicht richtig angeschlossen werden. (Auch werden die Punkte in horizontaler Richtung nicht perfekt genau dargestellt.)

Plotvergleich

Um die rechte Darstellung zu erstellen, wurde das DateFeld von einem Faktor in ein tatsächliches Datum konvertiert, jede Woche wurde mit einer einfachen Berechnung identifiziert (wobei die Wochen zwischen Samstag und Sonntag unterbrochen wurden) und die Linien wurden an Wochenenden durch Schleifen über die Wochen unterbrochen:

oracle$date <- as.Date(oracle$Date)
oracle$week.num <- (as.integer(oracle$date) + 3) %/% 7 
oracle$week <- as.Date(oracle$week.num * 7 - 3, as.Date("1970-01-01", "%Y-%m-%d"))

par(mfrow=c(1,2))
plot(as.factor(unclass(oracle$Date[1:120])), oracle$Open[1:120], type="l",
     main="Original Plot: Inset", xlab="Factor code")
plot(oracle$date[1:120], oracle$Open[1:120], type="n", ylab="Price", 
     main="Oracle Opening Prices")
tmp <- by(oracle[1:120,], oracle$week[1:120], function(x) lines(x$date, x$Open, lwd=2))

(Ein oracleDatumsäquivalent jeder Woche, das den Montag dieser Woche angibt , wurde ebenfalls im Datenrahmen gespeichert, da es zum Zeichnen wöchentlicher aggregierter Daten nützlich sein kann.)

Die ursprüngliche Absicht kann einfach durch Emulieren der letzten Zeile erreicht werden, um alle Daten anzuzeigen. Um einige Informationen zum saisonalen Verhalten hinzuzufügen, variiert das folgende Diagramm die Farbe pro Woche in jedem Kalenderjahr:

par(mfrow=c(1,1))
colors <- terrain.colors(52)
plot(oracle$date, oracle$Open, type="n", main="Oracle Opening Prices")
tmp <- by(oracle, oracle$week, 
          function(x) lines(x$date, x$Open, col=colors[x$week.num %% 52 + 1]))

Letzte Handlung

whuber
quelle
Keine Finanzperson, aber ich mag den saisonalen Trendtrick.
John Robertson
@ John Ursprünglich wurde die Farbe hinzugefügt, um das Auge zu unterstützen. Wenn ich mir das Ergebnis anschaue, finde ich es interessant, dass in fünf der sechs Jahre vor dem Aufblasen der Internetaktien im Jahr 2000 die orangefarbenen Wochen (ungefähr im Spätsommer) alle starke Aufwärtstrends zeigten. Danach scheint diese Tendenz verschwunden zu sein.
whuber
Ich bemerke das auch und frage mich, wie die Beziehung, wenn überhaupt, war.
John Robertson
whuber und @John Robertson - Vielleicht nicht zu eng miteinander verwandt, aber 1998 wechselte Microsoft auch mit SQL Server 7.0 / SQL Server 2000 zu seiner modernen Codebasis und bot Oracle bis 2000 eine stärkere Konkurrenz: en.wikipedia.org/wiki/ Microsoft_SQL_Server # Genesis
Rob
1
@ Andrew Ich würde "Date" schreiben. Wenn es sich um relative Daten handelt, würde ich - wenn es der Platz erlaubt - so etwas wie "Jahre seit dem 1. Januar 1990" schreiben. In diesem Beispiel hoffe ich, dass klar ist, dass nur der Plural "Jahre" ausreicht. Übrigens analysiere ich normalerweise zeitbezogene Daten anhand relativer Daten (für numerische Stabilität, einfache Lesbarkeit statistischer Zusammenfassungen usw.), konvertiere sie jedoch wieder in tatsächliche Daten für grafische Anzeigen (da Anzeigen aussagekräftige, interpretierbare Maßeinheiten verwenden sollten). .
whuber
1

Ich würde an den Wochenenden nicht interpolieren. Am Samstag werden nur sehr wenige Börsen gehandelt und am Sonntag keine, von denen ich weiß. Sie führen eine Schätzung für Daten ein, die es nie gab. Warum also nicht einfach Samstag und Sonntag aus dem Datensatz entfernen? Ich würde so etwas wie das Folgende tun:

require(ggplot2)
require(scales)
require(gridExtra)
require(lubridate)
require(reshape)

set.seed(12345)

# Create data frame from random data
daysback <- 1000 # number of days, only a few for this example
startdate <- as.Date(format(now()), format = "%Y-%m-%d") - days(daysback)
mydf <- data.frame(mydate = seq(as.Date(startdate), by = "day", length.out = daysback),
                   open = runif(daysback, min = 600, max = 800))

# Now that we have a data frame, remove the weekend days
mydf <- mydf[!(weekdays(as.Date(mydf$mydate)) %in% c('Saturday','Sunday')),] # remove weekend days
    # Calculate change, except for the first date
    mydf$diff <- c(NA, diff(mydf$open))
    # Remove first row with no 'diff' value
    firstdate <- head(mydf$mydate, 1)
mydf <- mydf[mydf$mydate > firstdate, ]

p <- ggplot(mydf, aes(x = mydate, y = diff)) +
    geom_bar(data = mydf, stat = "identity", fill = "red")

print(p)
Langsamer Lerner
quelle
Ja, das würde ich gerne bekommen. Aber gibt es nicht einen einfacheren Weg, indem Sie einfach Leerzeichen zwischen den Zeilen lassen, indem Sie die Wochenenden überspringen?
dbr
Ich denke, R geht davon aus, dass Daten vorhanden sind, die verwendet werden sollen. Sie sollten also diejenigen entfernen, die Sie nicht möchten. Immerhin ist es nicht schwer, der obige Code ist meistens überflüssig, das wichtige Bit ist das Entfernen und das erfordert nur eine Zeile, dh mydf <- mydf [! (Wochentage (as.Date (mydf $ mydate))% in% c ('Samstag', 'Sonntag')),]
SlowLearner
aber es ist bereits im Datensatz entfernt, die Daten für Samstag und Sonntag sind nicht enthalten
dbr
Ah. Ich habe Ihre Frage möglicherweise völlig falsch verstanden. Wenn Sie nur Daten glätten möchten, stimme ich zu, dass so etwas wie Löss der richtige Weg ist, aber das wird die Daten ändern. Oder Sie können ein sehr, sehr großes Bild des Diagramms erstellen, das die Details zeigt. Zum Beispiel 20.000 Pixel breit oder so.
SlowLearner
und wie wäre es mit der Verwendung von Dmitrys Lösung, aber anstatt den Mittelwert des vorherigen und nächsten Werts nur mit Nullen zu rechnen?
dbr
0

In Bezug auf das Aussehen Ihres Diagramms würde sich das Hinzufügen mehrerer Beschriftungen unter der x-Achse optisch verbessern. Das Aussehen des vorgeschlagenen Grundstücks finden Sie hier http://imgur.com/ZTNPniA

Ich weiß nicht, wie ich eine solche Handlung machen soll, es ist nur eine Idee (die ich in R nicht realisiert habe)

Robin Hood
quelle