2016-09-19 5 views
1

Ich habe eine Zeitreihendaten in zoo Format und einem anderen 2 Variablen Datenrahmen in POSIXct Format aufgezeichnet die 7 Paare von Starting und Endzeit, die die Zeitbereiche darstellen, die entfernt werden sollten . Die folgende Abbildung illustriert die Fragen grafisch. Die hervorgehobenen Regionen sind die Region, die ich bereits identifiziert habe und von der erwartet wird, dass sie entfernt wird.So entfernen Sie eine bestimmte Zeit im Zoo-Format

Ich weiß, dass window Funktion verwendet werden kann, um diese Regionen zu extrahieren, aber gibt es eine elegante Möglichkeit, einfach die Daten in dieser Region zu entfernen?

Machen Sie es einfach, eine beliebige Art zu löschen mehrere Perioden in einer Zeitreihe wie die Verwendung des Minus (-) - Zeichen, um Spalten oder Zeilen im Datenrahmen zu entfernen?

Illustration

Ergänzungs

Die identifizierte Periode in einem Datenrahmen ist, wie unten gezeigt (in POSIXct Format)

Die Zeitreihendaten sind in Standard Zoo Format

enter image description here

+1

Können Sie ein kleines Beispiel (simulierte Daten) zur Verfügung stellen? –

+0

Siehe [mcve] für ein reproduzierbares Beispiel. In diesem Fall habe ich eine in meiner Antwort angegeben. –

+0

Vielen Dank @ G.Grothiedieck, ich werde einen Blick darauf werfen und den Anweisungen in der Zukunft folgen. –

Antwort

3

In s hort, nein.

Daran erinnern, dass POSIXct speichert seine Informationen wirklich als double. Ihre gewünschten Verwendung des - Operator, ähnlich dem, was wir tun, für Vektor Indizes zielt wirklich auf integer Indizes wo vollkommene Gleichheit kann getestet werden.

Hier haben Sie nur Ungleichungen. So können Sie so etwas wie dies wollen (wo ich Datum bilden, da Sie nicht reproduzierbar etwas zur Verfügung gestellt hat):

R> set.seed(42) 
R> N <- 1000 
R> Z <- zoo(cumsum(rnorm(N)), order.by=Sys.time() + seq(0,by=3*60*60,length=N)) 
R> summary(Z) 
    Index        Z   
Min. :2016-09-19 06:36:25.31 Min. :-49.91 
1st Qu.:2016-10-20 11:51:25.31 1st Qu.:-27.43 
Median :2016-11-20 16:06:25.31 Median :-10.71 
Mean :2016-11-20 16:06:25.31 Mean :-15.89 
3rd Qu.:2016-12-21 21:21:25.31 3rd Qu.: -6.30 
Max. :2017-01-22 02:36:25.31 Max. : 9.06 

Nachdem wir nun einige Daten haben, lassen Sie uns nur Index-Logik verwenden, um einen bestimmten Zeitraum auszuschließen - was wir abgrenzen über ISOdatetime:

R> newZ <- Z[ ! (index(Z) >= ISOdatetime(2016,11,1,0,0,0) \ 
       & index(Z) <= ISOdatetime(2016,11,30,23,59,59)), ] 
R> 

wir die Daten ansehen können, und werden sehen, dass es die gewünschte Zeit ausgeschlossen, wie wir angestrebt hatten:

R> summary(newZ) 
    Index        newZ  
Min. :2016-09-19 06:36:25.31 Min. :-49.91 
1st Qu.:2016-10-12 23:06:25.31 1st Qu.:-33.73 
Median :2016-12-05 17:36:25.31 Median :-12.65 
Mean :2016-11-22 03:49:42.16 Mean :-17.74 
3rd Qu.:2016-12-29 10:06:25.31 3rd Qu.: -5.56 
Max. :2017-01-22 02:36:25.31 Max. : 9.06 
R> table(as.POSIXlt(index(newZ))$mon) # no November as expected 

    0 8 9 11 
169 94 248 248 
R> 

möglicherweise möchten Sie suchen ein t xts Indizierung obwohl.

2

Wenn Sie den Start- und Zielindizes der Untergruppen bekannt sind, können Sie die folgende verwenden, für jede der Untergruppen, x Annahme, daß die Daten im Zoo Format:

x[start.index:end.index] <- NA 
na.omit(x) 

Um Index zu finden

x 
2012-04-09 05:03:00 2012-04-09 05:04:00 2012-04-09 05:05:39 2012-04-09 05:09:00 2012-04-09 05:10:00 
        2     4     3     6     1 

which(index(x) >= '2012-04-09 05:09:00' & index(x) <= '2012-04-09 05:10:00') 
4 5 
0

Inspiriert von Sandipan Antwort schrieb ich eine kleine Funktion, wie unten die das Problem gelöst: der POSIXct Zeit in den Daten im Zoo-Format können Sie so etwas wie die folgenden verwenden. Wo dat ist eine Zeitreihe in zoo und hl.period ist die 2 Variablen Datenrahmen in POSIXct Format wie in der Frage gezeigt. Ich glaube jedoch, dass es einen eleganteren Weg geben sollte, um dieses Problem zu lösen.

Auch danke für Dirks Beitrag. Ihr Ansatz sieht vielversprechend aus. Aber da ich neu in der Zeitreihenanalyse bin, muss ich einige Hausaufgaben machen, um Ihren Ansatz zu verstehen.

del_periods<-function(dat,hl.period) 
{ 
    for (i in 1:nrow(hl.period)) 
    { 
     window(dat,start=hl.period[i,1],end=hl.period[i,2])<-NA 
     dat<-na.omit(dat) 
    } 
    return(dat) 
} 
0

Hier sind zwei mögliche Einzeiler. Vielleicht nicht so einfach wie gewünscht, aber sie sind kurz und die zweite verwendet Minus.

1) findInterval Zoo Indizes kann logisch so dass dieser Code mit findInterval mit logischem Zustand arbeitet, wo z ist die Eingang POSIXct Zooserie., st ist POSIXct Vektor beginnt und en ist ein entsprechendes POSIXct Vektor des Endes. Der unten stehende Code bildet c(st[1], en[1] + .001, st[2], en[2] + .001, ...), so dass die geradzahligen Intervalle Bereiche angeben, die beibehalten werden sollen, und ungerade, um ausgeschlossen zu werden. Dies setzt voraus, dass die Intervalle geordnet und nichtüberlappend sind, so dass st[1] < en[1] < st[2] < en[2] < ... Das scheint in der Frage der Fall zu sein.

z[ findInterval(index(z), c(rbind(st, en + .001))) %% 2 == 0 ] 

Beachten Sie, dass, wenn die Länge von st und en jeweils 1 sind dann vereinfacht es an:

z[ findInterval(index(z), c(st, en + .001)) != 1 ] 

2) Spiel Wenn die st und en Werte unter den index(z) Werte konnten wir abwechselnd Verwenden Sie match. Dies wäre zum Beispiel bei den in der Frage gezeigten Beginn und Ende der Fall, wenn z eine stündliche Reihe wäre. Dies nutzt die Tatsache aus, dass z[-(3:4)] die Elemente 3 und 4 aus der Zoo-Serie z ausschließt. Der folgende Code wandelt die POSIXct-Werte in Indizes zwischen 1, 2, 3, ..., Länge (z) um und gibt sie mit Minus aus.

z[ - unlist(Map(seq, match(st, index(z)), match(en, index(z)))) ] 

Beachten Sie, dass, wenn die Länge von st und en jeweils 1 ist dann vereinfacht es nur:

z[ - seq(match(st, index(z)), match(en, index(z)) ] 

Beispiel (2)

Zum Beispiel, versuchen Sie es mit diesem Eingänge:

library(zoo) 

tt <- seq(as.POSIXct("2011-01-01 00:00:00"), as.POSIXct("2011-01-04 23:00:00"), by="hour") 
z <- zoo(seq_along(tt), tt) 

st <- as.POSIXct(c("2011-01-02 13:00:00", "2011-01-04 15:00:00")) 
en <- as.POSIXct(c("2011-01-02 14:00:00", "2011-01-04 17:00:00")) 

Jetzt können wir das ausführen.

z0 <- z[ - unlist(Map(seq, match(st, index(z)), match(en, index(z)))) ] 
plot(z0, type = "p", pch = 20) 

Beachten Sie die zwei ausgeschlossenen Bereiche in der Grafik unten.

screenshot

Verwandte Themen