2012-05-11 11 views
7

Ich habe eine unregelmäßige Zeitreihe von Ereignissen (Beiträge) mit xts, und ich möchte die Anzahl der Ereignisse berechnen, die über ein rollendes wöchentliches Fenster (oder zweiwöchentlich oder 3 Tage usw.) auftreten. Die Daten sieht wie folgt aus:Rolling Window über unregelmäßige Zeitreihe

    postid 
2010-08-04 22:28:07 867 
2010-08-04 23:31:12 891 
2010-08-04 23:58:05 901 
2010-08-05 08:35:50 991 
2010-08-05 13:28:02 1085 
2010-08-05 14:14:47 1114 
2010-08-05 14:21:46 1117 
2010-08-05 15:46:24 1151 
2010-08-05 16:25:29 1174 
2010-08-05 23:19:29 1268 
2010-08-06 12:15:42 1384 
2010-08-06 15:22:06 1403 
2010-08-07 10:25:49 1550 
2010-08-07 18:58:16 1596 
2010-08-07 21:15:44 1608 

, die so etwas wie

    nposts 
2010-08-05 00:00:00  10 
2010-08-06 00:00:00  9 
2010-08-07 00:00:00  5 

für einen 2-Tage-Fenster erzeugen soll. Ich habe in rollapply, apply.rolling von PerformanceAnalytics, usw. geschaut, und sie nehmen alle regelmäßige Zeitreihendaten an. Ich habe versucht, alle Zeiten auf den Tag zu ändern, an dem die Post auftrat und etwas wie ddply an jedem Tag zu gruppieren, was mich nahe bringt. Ein Benutzer schreibt jedoch möglicherweise nicht jeden Tag, sodass die Zeitreihe immer noch unregelmäßig ist. Ich könnte die Lücken mit 0 füllen, aber das könnte meine Daten stark aufblasen und es ist schon ziemlich groß.

Was soll ich tun?

+2

Die Lösung für diesen zur Zeit nicht in dem XTS-Paket existieren, aber diese Anfrage kommt genug, dass ich zu erfahren, wie eine Lösung zu denken begonnen haben. –

+0

Haben Sie ein Update @JoshuaUlrich? Oder etwas in der Wirkung der Antwort unten, die fehlende Tage mit Nullen oder NAs Daten füllen, so dass wir dann 'rollapply' verwenden können? Ich denke, ich kann 'merge' verwenden ... – flodel

+0

@flodel: diese Frage benötigt nicht, was ich dachte, dass es getan hat (siehe meine Antwort). Ich dachte, sie wollten bei jeder Beobachtung in ihrer ursprünglichen Serie "n" Tage zurückschauen, was ein viel schwieriger zu lösendes Problem ist. –

Antwort

4

Dies scheint zu funktionieren:

# n = number of days 
n <- 30 
# w = window width. In this example, w = 7 days 
w <- 7 

# I will simulate some data to illustrate the procedure 
data <- rep(1:n, rpois(n, 2)) 

# Tabulate the number of occurences per day: 
# (use factor() to be sure to have the days with zero observations included) 
date.table <- table(factor(data, levels=1:n)) 

mat <- diag(n) 
for (i in 2:w){ 
    dim <- n+i-1 
    mat <- mat + diag(dim)[-((n+1):dim),-(1:(i-1))] 
    } 

# And the answer is.... 
roll.mean.7days <- date.table %*% mat 

Scheint nicht zu langsam zu sein (obwohl die mat Matrix Dimensionen n * n erhalten). Ich habe versucht, n = 30 durch n = 3000 zu ersetzen (was eine Matrix von 9 Millionen Elementen = 72 MB erzeugt) und es war immer noch ziemlich schnell auf meinem Computer. Bei sehr großen Datensätzen sollten Sie zuerst eine Teilmenge versuchen .... Es ist auch schneller, einige der Funktionen im Matrix-Paket (bandSparse) zu verwenden, um die mat Matrix zu erstellen.

+0

Dies ist eine nette Methode, um ein Rolling-Fenster auf etwas anzuwenden, aber wenn Sie kein Beispiel angeben, wie dies auf eine aktuelle Zeitreihe angewendet wird (als POSIXct-Date-Time-Objekte wie in der ursprünglichen Frage auszudrücken), ist das kaum möglich Beantwortet die Frage. – plannapus

+0

Mit Vektoren von unregelmäßig verteilten POSIXct-Objekten 'data <- sample (seq (as.POSIXct (" 2012/01/01 "), as.POSIXct (" 2012/01/31 "), by =" Stunden ") , 30) ', können Sie Ihre Zeile' date.table' durch folgende ersetzen: 'date.table <- table (cut (data," days "))' und gehen Sie dann wie Sie vor, und es sollte den Trick machen. – plannapus

+0

plannapus, danke für Ihre Ergänzungen zu POSIXct Objekten. –

3

Hier ist eine Lösung xts mit:

x <- structure(c(867L, 891L, 901L, 991L, 1085L, 1114L, 1117L, 1151L, 
    1174L, 1268L, 1384L, 1403L, 1550L, 1596L, 1608L), .Dim = c(15L, 1L), 
    index = structure(c(1280960887, 1280964672, 1280966285, 
    1280997350, 1281014882, 1281017687, 1281018106, 1281023184, 1281025529, 
    1281050369, 1281096942, 1281108126, 1281176749, 1281207496, 1281215744), 
    tzone = "", tclass = c("POSIXct", "POSIXt")), class = c("xts", "zoo"), 
    .indexCLASS = c("POSIXct", "POSIXt"), tclass = c("POSIXct", "POSIXt"), 
    .indexTZ = "", tzone = "") 
# first count the number of observations each day 
xd <- apply.daily(x, length) 
# now sum the counts over a 2-day rolling window 
x2d <- rollapply(xd, 2, sum) 
# align times at the end of the period (if you want) 
y <- align.time(x2d, n=60*60*24) # n is in seconds