2016-09-28 4 views
2

I dieser Datenrahmen durch END TIME sortiert haben:Prüfung für überlappende Intervalle Start- und Endzeiten

df = data.frame(ID= c(1,1,1,1,1,1,1), NumberInSequence= c(1,2,3,4,5,6,7), 
       StartTime = as.POSIXct(c("2016-01-15 18:02:11 GMT","2016-01-15 18:10:33 GMT","2016-01-15 18:25:08 GMT", 
               "2016-01-15 18:33:56 GMT","2016-01-15 18:21:03 GMT","2016-01-15 19:55:09 GMT","2016-01-15 19:57:03 GMT")) , 
         EndTime = as.POSIXct(c("2016-01-15 18:02:17 GMT","2016-01-15 18:10:39 GMT","2016-01-15 18:25:14 GMT", 
               "2016-01-15 18:34:02 GMT","2016-01-15 19:53:17 GMT","2016-01-15 19:56:15 GMT","2016-01-15 19:58:17 GMT")) 
         ) 

Jede Reihe ist ein Zeitintervall mit einer Startzeit und Endzeit

df 

ID NumberInSequence   StartTime    EndTime 
1 1    1 2016-01-15 18:02:11 2016-01-15 18:02:17 
2 1    2 2016-01-15 18:10:33 2016-01-15 18:10:39 
3 1    3 2016-01-15 18:25:08 2016-01-15 18:25:14 
4 1    4 2016-01-15 18:33:56 2016-01-15 18:34:02 
5 1    5 2016-01-15 18:21:03 2016-01-15 19:53:17 
6 1    6 2016-01-15 19:55:09 2016-01-15 19:56:15 
7 1    7 2016-01-15 19:57:03 2016-01-15 19:58:17 

I dann Verwenden Sie dplyr, um einige Felder hinzuzufügen, die die nächste Startzeit und die Wartezeit berechnen, die die Differenz zwischen NextStartTime und EndTime darstellt. Dadurch wird die Spalte "WaitTime" erstellt, die in den meisten Fällen funktioniert, sofern keine Überlappungen vorhanden sind.

df %>% group_by(ID) %>% 
     mutate(
     NextStartTime = lead(StartTime)[ifelse(lead(NumberInSequence) == (NumberInSequence + 1), TRUE, NA)] , 
     WaitTime = difftime(NextStartTime,EndTime, units = 's') 
     #max_s = max(StartTime) #, 
    # cum_max_s = as.POSIXct(cummin(as.numeric(StartTime)),origin="1970-01-01") 
    ) 


    ID NumberInSequence   StartTime    EndTime  NextStartTime WaitTime 
1 1    1 2016-01-15 18:02:11 2016-01-15 18:02:17 2016-01-15 18:10:33 496 secs 
2 1    2 2016-01-15 18:10:33 2016-01-15 18:10:39 2016-01-15 18:25:08 869 secs 
3 1    3 2016-01-15 18:25:08 2016-01-15 18:25:14 2016-01-15 18:33:56 522 secs 
4 1    4 2016-01-15 18:33:56 2016-01-15 18:34:02 2016-01-15 18:21:03 -779 secs 
5 1    5 2016-01-15 18:21:03 2016-01-15 19:53:17 2016-01-15 19:55:09 112 secs 
6 1    6 2016-01-15 19:55:09 2016-01-15 19:56:15 2016-01-15 19:57:03 48 secs 
7 1    7 2016-01-15 19:57:03 2016-01-15 19:58:17    <NA> NA secs 

Jetzt brauche ich eine Spalte hinzuzufügen, genannt „FLAG“ mit dem Wert OK wird oder nicht OK, wo

„OK“ bedeutet das Intervall NICHT enitrely oder teilweise entweder in einem anderen Intervall. So haben Intervalle mit "OK" keine Überschneidung mit anderen Intervallen.

"NICHT OK" bedeutet, dass das Intervall entweder teilweise oder vollständig in einem anderen Intervall liegt. So haben sich Intervalle mit "NOT OK" mit anderen Intervallen überschnitten.

Ich habe die Intervalle unten und was das Ergebnis der FLAG-Säule mit einer kurzen Beschreibung sollte

StartTime    EndTime    FLAG 
2016-01-15 18:02:11 2016-01-15 18:02:17  OK - this interval does not overlap with other intervals 
2016-01-15 18:10:33 2016-01-15 18:10:39  OK - this interval does not overlap with other intervals 
2016-01-15 18:25:08 2016-01-15 18:25:14  NOT OK - this inerval is within the 18:21:03 start time interval 
2016-01-15 18:33:56 2016-01-15 18:34:02  NOT OK - this inerval is within the 18:21:03 start time interval 
2016-01-15 18:21:03 2016-01-15 19:53:17  NOT OK - this interval contains other intervals 
2016-01-15 19:55:09 2016-01-15 19:56:15  OK - this interval does not overlap with other intervals 
2016-01-15 19:57:03 2016-01-15 19:58:17  OK - this interval does not overlap with other intervals 

ich mit cummin in oder cummax in dplyr gesucht ..... vielleicht ... .

cum_max_s = as.POSIXct(cummin(as.numeric(StartTime)),origin="1970-01-01") 

Antwort

2

Hier ist mein Versuch für Sie. Ich denke, foverlaps() in der data.table-Paket ist unser Freund für diese Art von Fall. Sie können einige Beispiele zu SO finden. Sie möchten sie überprüfen, um die Funktion zu verstehen. Sie müssen eine Dummy-Data.table erstellen, einschließlich Start- und Endzeit. In deinem Fall hast du sie. Ich habe dummy mit minimalen Informationen erstellt. Dann verwenden Sie setkey() und verwenden foverlaps().

# Create a dummy dt for hoverlaps. 
dummy <- setDT(df2)[, 1:4, with = FALSE] 

# Use foverlaps(). 
setkey(setDT(df2), StartTime, EndTime) 
foo <- foverlaps(dummy, setDT(df2), by.x = c("StartTime", "EndTime")) 

Jetzt ist es an der Zeit, die Daten zu bereinigen. Für jede NumberInSequence, wenn es mehr als 1 überlappende Intervalle (n> 1) gibt, entfernen Sie eine Zeile, die identische Start- und Endzeit hat (StartTime == i.StartTime & EndTime == i.EndTime). Entfernen Sie dann doppelte Zeilen für jede NumberInSequence. Wenn Sie nur eine Zeile haben, die anzeigt, dass Sie mit einem anderen Intervall überlappen, ist das genug, oder? Wenn StartTime == i.StartTime & EndTime == i.EndTime schließlich TRUE ist, bedeutet dies, dass kein anderes Intervall mit dem Intervall überlappt. Also, du sagst . Ansonsten, NOT OK. Entfernen Sie ggf. zusätzliche Spalten später.

foo[,.SD[!(StartTime == i.StartTime & EndTime == i.EndTime & .N > 1)], 
     by = c("ID","NumberInSequence")][!duplicated(NumberInSequence)][, 
      check := ifelse(StartTime == i.StartTime & EndTime == i.EndTime, 
          "OK", "NOT OK")] -> out  
print(out) 

# ID NumberInSequence   StartTime    EndTime  NextStartTime WaitTime i.ID i.NumberInSequence 
#1: 1    1 2016-01-15 18:02:11 2016-01-15 18:02:17 2016-01-15 18:10:33 496 secs 1     1 
#2: 1    2 2016-01-15 18:10:33 2016-01-15 18:10:39 2016-01-15 18:25:08 869 secs 1     2 
#3: 1    5 2016-01-15 18:21:03 2016-01-15 19:53:17 2016-01-15 19:55:09 112 secs 1     3 
#4: 1    3 2016-01-15 18:25:08 2016-01-15 18:25:14 2016-01-15 18:33:56 522 secs 1     5 
#5: 1    4 2016-01-15 18:33:56 2016-01-15 18:34:02 2016-01-15 18:21:03 -779 secs 1     5 
#6: 1    6 2016-01-15 19:55:09 2016-01-15 19:56:15 2016-01-15 19:57:03 48 secs 1     6 
#7: 1    7 2016-01-15 19:57:03 2016-01-15 19:58:17    <NA> NA secs 1     7 

#   i.StartTime   i.EndTime check 
#1: 2016-01-15 18:02:11 2016-01-15 18:02:17  OK 
#2: 2016-01-15 18:10:33 2016-01-15 18:10:39  OK 
#3: 2016-01-15 18:25:08 2016-01-15 18:25:14 NOT OK 
#4: 2016-01-15 18:21:03 2016-01-15 19:53:17 NOT OK 
#5: 2016-01-15 18:21:03 2016-01-15 19:53:17 NOT OK 
#6: 2016-01-15 19:55:09 2016-01-15 19:56:15  OK 
#7: 2016-01-15 19:57:03 2016-01-15 19:58:17  OK 
Verwandte Themen