2017-09-19 2 views
1

Ich möchte die Zeiten in der Datum-Uhrzeit-Spalte vergleichen (das ist die Indexspalte eines xts Objekts). Sagen wir, ich Datensatz namens My_Data wie folgt gegeben:Vergleichen von Zeiten in XTS-Objekten in R

My_Data <- structure(c(5, 2, 4, 8, 9), index = structure(c(1184599268.133, 
    1184602925.231, 1184604481.931, 1184685301.769, 1184685668.133), tzone = "", 
    tclass = c("POSIXct", "POSIXt")), class = c("xts", "zoo"), 
    .indexCLASS = c("POSIXct", "POSIXt"), tclass = c("POSIXct", "POSIXt"), 
    .indexTZ = "", tzone = "", .Dim = c(5L, 1L), .Dimnames = list(NULL, "Price")) 

Beachten Sie, dass, da die Daten ein xts Objekt ist, kann das Datum-Zeit-Spalte im Index des Datensatzes ist und bezeichnet werden mit der Funktion index(My_Data)

Für mein Programm, das ich über meine Dataset bin Iterieren, und ich würde gerne wissen, wann das Datum ändert im Index der Daten (die in den obigen Daten würden von den Terminen 2007-07-16-2007-07-17 gehen) Zu diesem Zweck habe ich versucht, mit der folgenden Funktion das Datum in jeder Indexzeile zu extrahieren:

Wo diese Funktion das Datum aus dem Index der ersten Zeile meiner Daten (das ist 2007-07-16) extrahiert wird. So eine beliebige Zeile zu extrahieren i Ich benutze

(format(index(My_Data)[i], format = "%Y-%m-%d")) 

Und zwei verschiedene Reihen zu vergleichen, um herauszufinden, ob die Daten unterschiedlich sind benutze ich:

(format(index(My_Data)[1], format = "%Y-%m-%d")) < 
(format(index(My_Data)[2], format = "%Y-%m-%d")) 

, die das Datum des ersten Indexzeile vergleicht mit dem Datum aus der zweiten Indexzeile.

Dieser Vergleich ist jedoch extrem langsam - ich habe diesen Vergleich mit dem microbenchmark Paket überprüft und es liegt in der Größenordnung von Millisekunden! Da ich eine große Menge an Daten habe, habe ich mich gefragt, ob es eine effizientere Möglichkeit gibt zu überprüfen, wann sich die Daten im Index geändert haben, da diese Methode meinen Code stark verlangsamen wird.

Antwort

1

Sie haben (mindestens) ein paar bessere Optionen. Wählen Sie diejenige aus, die für Ihre Situation am besten geeignet ist.

Sie können .indexDate() und diff() verwenden, um Sie zu informieren, wenn sich das Datum des Index ändert. Denken Sie daran, dass diff() ein Objekt mit einer Länge zurückgibt, die eine Beobachtung weniger als seine Eingabe hat, also müssen Sie es mit einer führenden Null oder NA verketten.

merge(My_Data, newdate = c(0, diff(.indexDate(My_Data)))) 
#      Price newdate 
# 2007-07-16 10:21:08  5  0 
# 2007-07-16 11:22:05  2  0 
# 2007-07-16 11:48:01  4  0 
# 2007-07-17 10:15:01  8  1 
# 2007-07-17 10:21:08  9  0 

Sie können auch endpoints() verwenden Sie die letzte Beobachtung in Ihrer Serie für jeden Tag zu erzählen. Denken Sie daran, dass endpoints() immer einen Vektor zurückgibt, der mit 0 beginnt und mit nrow(x) endet.

endpoints(My_Data, "days") 
# [1] 0 3 5 

Der Grund Ihrer Lösung Charakter mehr ist nimmt Strings, weil die Umwandlung teuer ist. Ich nehme auch an, dass die Verwendung logischer Operatoren für Zeichenketten teurer ist als für Zahlen, da die Sortierung von Zeichenfolgen von der Sortierungsreihenfolge Ihrer Ländereinstellung abhängt (daher sind wahrscheinlich mehr Operationen möglich).

+0

Danke, ja, nach dem Aussehen könnte es besser für mich sein, sie in Zahlen zu konvertieren. '.indexDate()' und dann einen Vergleich verwenden, also werde ich das versuchen :) – reallybadstatdude

Verwandte Themen