2016-10-18 4 views
4

Ich habe ein Dataset, das kategorisierte Ereignisse aufzeichnet, die zwei Zeitpunkte t1 und t2 haben, wobei t2 aways> = t1 ist. Ereignisse sind kategorisiert z1, z2, z3 oder NA (nicht kategorisiert). Für jede Gruppe (grp) möchte ich Ereignisse identifizieren, bei denen t1 innerhalb eines bestimmten Zeitraums eines kategorisierten t2-Ereignisses in der Gruppe liegt. In meinem Beispiel habe ich diese t2-Ereignisse als Referenzdaten bezeichnet. Die Schleifenprozedur zeigt, was ich benötige, ist aber über einen großen Datensatz hoffnungslos ineffizient. Ich benötige dies für einen Datensatz mit mehreren Millionen Zeilen mit mehr als einer Million Gruppen.Gruppenspezifische zeitgesteuerte Ereignisse innerhalb eines definierten Zeitraums identifizieren

Ich habe auch meine Versuche gezeigt, dies effizienter mit der Syntax data.table zu codieren. Meine Methode besteht darin, die Menge der Referenzdaten für jede Gruppe dem Vektor "ref" zuzuweisen, dann für jede Zeile in der Gruppe die Differenz zwischen t1 und den Referenzdaten zu berechnen und diese Intervalle gegen ein spezifiziertes Intervall zu testen, das dann zurückkehrt Ein einzelner Boolescher Wert, der angibt, ob das zeilenspezifische t1 innerhalb von 30 Tagen von irgendeinem der Referenzdaten liegt. Wenn ich jede Gruppe auf ein einzelnes Referenzdatum beschränke (indem ich das erste Datum [1] nehme), funktioniert der Code, aber wenn ich nach Bedarf mehrere Referenzdaten zulasse, gibt der Code Fehler zurück. Offensichtlich verstehe ich nicht, was die Datentabelle innerhalb der j-Anweisung macht. Könnte jemand erklären, was ich falsch verstanden habe und eine effiziente data.table Lösung vorschlagen.

Beispieldaten

library("data.table") 
DT <-read.table(text= 
"grp,zcat,t1,t2 
a,NA,2007-03-18,2007-03-28 
a,z1,2007-08-04,2007-08-14 
a,NA,2007-08-21,2007-08-23 
a,NA,2007-11-21,2007-11-29 
a,z1,2007-12-10,2007-12-13 
a,z2,2008-02-16,2008-02-19 
a,NA,2008-03-14,2008-03-21 
a,NA,2008-05-27,2008-06-03 
b,NA,2003-04-22,2003-04-27 
b,z3,2003-05-11,2003-05-23 
b,z1,2003-07-16,2003-08-02 
c,z3,2011-01-18,2011-02-07 
c,z3,2011-03-01,2011-03-13 
c,NA,2011-03-30,2011-04-11 
c,NA,2011-05-21,2011-05-28", 
header=TRUE, sep=",", stringsAsFactors=FALSE, na.strings="NA", colClasses="character") 
DT <-data.table(DT) 
setorder(DT,grp,t1) 

Referenzdaten durch Gruppen

GRP-a: "2007-08-14" "2007-12-13" "2008-02-19"

GRP-b: "2003-05-23" "2003-08-02"

GRP-c: "2011-02-07" "2011-03-13"

Schleifenprozedur - ok

out<-c() 
for(i in 1:nrow(DT)){ 
    ref <-DT[grp == grp[i] & !is.na(zcat),t2] 
    temp <-as.Date(DT$t1[i]) - as.Date(ref) 
    out[i] <-any(temp >=0 & temp <31) 
    rm(ref,temp) 
    # ref; delta; delta >=0 & delta <31 
    if(i==nrow(DT)){DT[, newvar :=out]; rm(out)} 
} 

data.table Codierung versucht

die ersten beiden Beispiele ok arbeiten, aber eine einzige Referenzdaten für jede Gruppe verwenden, das dritte Beispiel verwendet das gleiche Prinzip mit allen Referenzdaten und schlägt fehl. Das Problem scheint in zu sein, wie j-Anweisung mehr Intervalle Handling Werte

DT[,{ref=t2[!is.na(zcat)]; delta=as.Date(t1) - as.Date(ref)[1]; delta >0 & delta <30}, by=grp] 

DT[,{ref=t2[!is.na(zcat)][1]; delta=as.Date(t1) - as.Date(ref); delta >0 & delta <30}, by=grp] 

DT[,{ref=t2[!is.na(zcat)]; delta=as.Date(t1) - as.Date(ref); any(delta >0 & delta <30)}, by=grp] 

Antwort

2

die neueste Version verwenden (1.9.8+):

DT[, `:=`(t1 = as.Date(t1), t2 = as.Date(t2), newvar = FALSE)] 

DT[DT[!is.na(zcat), .(grp, t2, t2.end = t2 + 31)], 
    on = .(grp, t1 >= t2, t1 < t2.end), 
    newvar := TRUE] 
+0

Ich verstehe Linie-1, aber lückenhaft auf Linie-2. Führen Sie eine Verknüpfung zwischen DT und einer Teilmenge von DT, die die Referenzdaten mit t2 + 31 enthält, als Variable t2.end aus, die mein Zeitintervall definiert. Und dieser Join setzt newvar auf TRUE, wo es eine Übereinstimmung gibt. Auch wenn ich Zeile 2 laufe, bekomme ich eine Nachricht ... konnte die Funktion nicht finden. " Ich benutze R3.2.2 GUI 1.66 Mavericks Build (6996) auf Mac/OSX 10.11.6. Nicht sicher, wie sich dies auf Ihre Notiz bezieht, die Sie verwenden v1.9.7 + – user6899412

+0

Scheint, als ob Sie es verstanden haben. Sie müssen 'data.table' Version 1.9.7+ haben - sonst wird es nicht funktionieren. – eddi

+0

ok, jetzt mit Github-Version arbeiten, müssen diese auf meine echten Daten laufen, um alles OK und Geschwindigkeit zu überprüfen, vielen Dank – user6899412

Verwandte Themen