Was ist eine effiziente Methode zum Partitionieren und Intervalle von timestamped Zeilen in einem Datenrahmen aggregieren?
Frage
Von einem Datenrahmen mit timestamped Zeilen (strptime Ergebnisse), was ist die beste Methode für die Statistik für Intervalle Aggregation?
Die Intervalle könnten eine Stunde, ein Tag, usw.
Es gibt die aggregate
Funktion, aber das nicht hilft mit jeder Zeile zu einem Intervall zuweisen. Ich plane eine Spalte mit dem Datenrahmen auf das Hinzufügen, das Intervall bezeichnet und die Verwendung dieser mit aggregate
, aber wenn es eine bessere Lösung ist würde es groß sein, es zu hören.
Danke für alle Hinweise!
Beispieldaten
fünf Reihen mit Zeitstempel unterteilt in 15-Minuten-Takt um 03:00 Uhr beginnt.
Intervall 1
- "2010-01-13 03.02.38 UTC"
- "2010-01-13 03.08.14 UTC"
- "2010-01-13 03.14.52 UTC"
Intervall 2
- "2010-01-13 03.20.42 UTC"
- "2010-01-13 03.22.19 UTC"
Fazit
sollte eine Zeitreihe Paket wie xts
Mit der Lösung sein; aber ich hatte keinen Erfolg, sie und aufgewickelte mit cut
verwenden. Da ich derzeit nur auf Plot Histogramme benötigen, mit Reihen von Intervall gruppiert, das war genug.
cut
verwendet wird gern so:
interv <- function(x, start, period, num.intervals) {
return(cut(x, as.POSIXlt(start)+0:num.intervals*period))
}
Lösung
Standardfunktionen zur Teilvektoren sind cut
und findInterval
:
v <- as.POSIXct(c(
"2010-01-13 03:02:38 UTC",
"2010-01-13 03:08:14 UTC",
"2010-01-13 03:14:52 UTC",
"2010-01-13 03:20:42 UTC",
"2010-01-13 03:22:19 UTC"
))
# Your function return list:
interv(v, as.POSIXlt("2010-01-13 03:00:00 UTC"), 900)
# [[1]]
# [1] "2010-01-13 03:00:00"
# [[2]]
# [1] "2010-01-13 03:00:00"
# [[3]]
# [1] "2010-01-13 03:00:00"
# [[4]]
# [1] "2010-01-13 03:15:00 CET"
# [[5]]
# [1] "2010-01-13 03:15:00 CET"
# cut returns factor, you must provide proper breaks:
cut(v, as.POSIXlt("2010-01-13 03:00:00 UTC")+0:2*900)
# [1] 2010-01-13 03:00:00 2010-01-13 03:00:00 2010-01-13 03:00:00
# [4] 2010-01-13 03:15:00 2010-01-13 03:15:00
# Levels: 2010-01-13 03:00:00 2010-01-13 03:15:00
# findInterval returns vector of interval id (breaks like in cut)
findInterval(v, as.POSIXlt("2010-01-13 03:00:00 UTC")+0:2*900)
# [1] 1 1 1 2 2
Für das Protokoll: cut
ein Verfahren zur POSIXt
Typ hat, aber leider gibt es keine Möglichkeit, start
Argument zu liefern, Wirkung ist:
cut(v,"15 min")
# [1] 2010-01-13 03:02:00 2010-01-13 03:02:00 2010-01-13 03:02:00
# [4] 2010-01-13 03:17:00 2010-01-13 03:17:00
# Levels: 2010-01-13 03:02:00 2010-01-13 03:17:00
Wie Sie es von Anfang an 03.02.00 zu sehen. Sie könnten verwirren mit Etiketten von Ausgabefaktor (convert Etiketten zu Zeit, rund irgendwie und convert zurück zum Charakter).
Andere Tipps
Verwenden Sie ein Zeitreihen-Paket. Das XTS-Paket enthält Funktionen konzipiert, dass speziell zu tun. Oder schauen Sie sich die aggregierte und rollapply Funktionen im Zoo-Paket.
Das rmetrics ebook hat eine nützliche Diskussion, darunter ein Performance-Vergleich der verschiedenen Pakete: https://www.rmetrics.org/files/freepdf/TimeSeriesFAQ.pdf
Bearbeiten : Blick auf meine Antwort auf diese Frage . Grundsätzlich müssen Sie jeden Zeitstempel in einem bestimmten Intervall verkürzen und führen Sie dann die Aggregation, die neuen verkürzten Zeitstempel als Gruppierung Vektor verwendet wird.
Dies ist eine interessante Frage; mit der Verbreitung der verschiedenen Zeitserienpakete und Methoden, sollte es für den Binning unregelmäßige Zeitreihe außer Kraft, die von bruter ein Ansatz sein, dass die OP vorschlägt. Hier ist ein „High-Level“ Art und Weise, die Intervalle zu erhalten, die Sie dann für aggregate
et al verwenden können, eine Version von cut
mit definierten für chron
Objekte.
require(chron)
require(timeSeries)
my.times <- "
2010-01-13 03:02:38 UTC
2010-01-13 03:08:14 UTC
2010-01-13 03:14:52 UTC
2010-01-13 03:20:42 UTC
2010-01-13 03:22:19 UTC
"
time.df <- read.delim(textConnection(my.times),header=FALSE,sep="\n",strip.white=FALSE)
time.seq <- seq(trunc(timeDate(time.df[1,1]),units="hours"),by=15*60,length=nrow(time.df))
intervals <- as.numeric(cut(as.chron(as.character(time.df$V1)),breaks=as.chron(as.character(time.seq))))
Sie erhalten
intervals
[1] 1 1 1 2 2
, die Sie können nun Anfügen an den Datenrahmen und Aggregat.
Die coersion Akrobatik oben (von Zeichen zu Timedate zum Charakter zu chron) ist ein wenig unglücklich, also, wenn es saubere Lösungen für Binning unregelmäßige Zeitdaten xts oder eine der anderen Zeitreihen-Pakete mit, ich würde gerne hören, sie auch! ..
Ich bin auch neugierig zu wissen, was der effizienteste Ansatz wäre für Binning große Hochfrequenz unregelmäßige Zeitreihe, beispielsweise 1-Minuten-Volumen Balken auf Tickdaten für ein sehr flüssiges Lager zu schaffen.