2016-06-17 10 views
2

Meine Daten sieht wie folgt aus:wie durch in der Nähe Werte gruppieren data.tables

ID1  ID2  Time   diff 
1: 1958616 P209576 4/15/2016 7:46 NA mins 
2: 1958493 P209580 3/23/2016 9:41 -33005.16793 mins 
3: 1958493 P209580 3/25/2016 15:41 3240.09742 mins 
4: 1958493 P209580 3/30/2016 10:22 6880.65360 mins 
5: 1958492 P209580 3/30/2016 11:31 69.00078 mins 
6: 1958493 P209580 4/11/2016 10:07 17196.62313 mins 

Was ich möchte alle IDs zu tun ist, Gruppe, die innerhalb eines 8-Stunden-Zeitfenster voneinander auftreten und auch geben Sie nach der Gruppierung die Anzahl der eindeutigen ID1s zurück. Im obigen Beispiel wären die Zeilen 4 & 5 seit abs(diff) < 60*8 gruppiert.

Ich habe data[, diff := TIME - shift(TIME)] verwendet, um die Diff-Spalte zu generieren.

Mein idealer Ausgang würde in etwa so aussieht

num_of_unique_id1 ID2  Initial_time 
1: 1     P209576 4/15/2016 7:46 
2: 1     P209580 3/23/2016 9:41 
3: 1     P209580 3/25/2016 15:41 
4: 2     P209580 3/30/2016 10:22 
5: 1     P209580 4/11/2016 10:07 

Ich denke, dass num_of_unique_id1 mit .SD und length(unique(ID1)) erstellt werden könnte, aber nicht sicher, wie Spalte für by = Parameter zu erstellen.

Ich weiß, dass es auch Grenzprobleme geben wird (A ist innerhalb von 8 Stunden von B und B ist innerhalb von 8 Stunden von C, aber A und C sind mehr als 8 Stunden voneinander entfernt) und in diesen Fällen denke ich würde ich mag es alles in eine Reihe zu gruppieren.

Ausgang dput(data)

structure(list(ID1 = c("1958616", "1958493", "1958493", "1958493", 
"1958492", "1958493"), ID2 = c("P209576", "P209580", "P209580", 
"P209580", "P209580", "P209580"), Time = structure(c(1460706387.438, 
1458726077.362, 1458920483.207, 1459333322.423, 1459337462.47, 
1460369259.858), class = c("POSIXct", "POSIXt"), tzone = "GMT"), 
    diff = structure(c(NA, -33005.1679333329, 3240.09741666714, 
    6880.65360000133, 69.0007833321889, 17196.6231333335), units = "mins", class = "difftime")), .Names = c("ID1", 
"ID2", "Time", "diff"), class = c("data.table", "data.frame"), row.names = c(NA, 
-6L), .internal.selfref = <pointer: 0x1ce9a28>) 
+0

Können Sie 'dput' auf dem" Kopf "Ihrer Daten verwenden, um reproduzierbare Daten bereitzustellen? Siehe [hier] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – alexperrone

+0

"Was ich tun möchte, ist die Gruppierung aller IDs, die innerhalb eines auftreten 8 Stunden Zeitfenster voneinander "... möchten Sie innerhalb von 8 Stunden Zeitfenster des * vorherigen * (zeitlich) Eintrags? Warum sortieren Sie die Daten nicht zuerst nach Zeit? – alexperrone

+0

Oder müssen die Daten in der Reihenfolge bleiben, in der sie kommen? – alexperrone

Antwort

4

Wenn die Daten in der Zeit geordnet sind, können wir die diff berechnen und einzigartige Gruppen zuordnen cumsum verwenden.

data <- data[order(Time)] 
data[ , diff := NULL] # we will re-compute diff in hours 
data[ , diff_hours := as.numeric(c(0, diff(Time)))] 
##  ID1  ID2    Time diff_hours 
## 1: 1958493 P209580 2016-03-23 09:41:17 0.000000 
## 2: 1958493 P209580 2016-03-25 15:41:23 54.001624 
## 3: 1958493 P209580 2016-03-30 10:22:02 114.677560 
## 4: 1958492 P209580 2016-03-30 11:31:02 1.150013 
## 5: 1958493 P209580 2016-04-11 10:07:39 286.610386 
## 6: 1958616 P209576 2016-04-15 07:46:27 93.646550 

window <- 8 # the time window in hours 
data[ , group := cumsum(diff_hours > window) + 1] 
data[ , num_of_unique_id1 := uniqueN(ID1), by = group] 
##  ID1  ID2    Time diff_hours group num_of_unique_id1 
## 1: 1958493 P209580 2016-03-23 09:41:17 0.000000  1     1 
## 2: 1958493 P209580 2016-03-25 15:41:23 54.001624  2     1 
## 3: 1958493 P209580 2016-03-30 10:22:02 114.677560  3     2 
## 4: 1958492 P209580 2016-03-30 11:31:02 1.150013  3     2 
## 5: 1958493 P209580 2016-04-11 10:07:39 286.610386  4     1 
## 6: 1958616 P209576 2016-04-15 07:46:27 93.646550  5     1 

Hinweis, dass die beiden Datenpunkte auf 2016-03-30 innerhalb von etwa einer Stunde voneinander gleich group zugeordnet sind und die num_of_unique_id1 (pro Gruppe) 2 ist, während alle anderen Datenpunkte in ihrer eigenen Gruppe.

+0

'Cumsum' ist ein netter Trick! Vielen Dank – yingw