effizient nach Gruppen in einer einzigen R-data.tabelle lokalisiert

8

Ich habe eine große, breite data.table (20m Zeilen), die durch eine Personen-ID verschlüsselt wird, aber mit vielen Spalten (~ 150), die viele Nullwerte haben. Jede Spalte ist ein aufgezeichneter Status / Attribut, das ich für jede Person mitnehmen möchte. Jede Person kann zwischen 10 und 10.000 Beobachtungen haben und es sind etwa 500.000 Menschen im Set. Werte von einer Person können nicht in die folgende Person "bluten". Daher muss meine Lösung die ID-Spalte der Person und die Gruppe entsprechend berücksichtigen.

Zu Demonstrationszwecken - hier ist eine sehr kleine Beispieleingabe:

%Vor%

Es sieht so aus:

%Vor%

Meine erwartete Ausgabe sieht so aus:

%Vor%

Ich habe eine data.table -Lösung gefunden, die funktioniert, aber auf meinen großen Datensätzen ist es schrecklich langsam:

%Vor%

Ich habe äquivalente Lösungen mit dplyr gefunden, die gleichermaßen langsam sind.

%Vor%

Ich hatte die Hoffnung, dass ich mit der data.table -Funktionalität einen rollenden Self-Join entwickeln könnte, aber ich kann es einfach nicht richtig machen (ich vermute, ich müsste .N verwenden, aber ich einfach habe es nicht herausgefunden).

An dieser Stelle denke ich, dass ich etwas in Rcpp schreiben muss, um den gruppierten locf effizient anzuwenden.

Ich bin neu bei R, aber ich bin nicht neu in C ++ - also bin ich zuversichtlich, dass ich es schaffen kann. Ich habe gerade das Gefühl, dass es eine effiziente Möglichkeit geben sollte, dies in R mit data.table zu tun.

    
carl.anderson 05.05.2016, 20:59
quelle

1 Antwort

14

Ein sehr einfaches na.locf kann durch Weiterleiten ( cummax ) der Nicht- NA -Indizes ( (!is.na(x)) * seq_along(x) ) und der entsprechenden Untermenge erstellt werden:

%Vor%

Dies repliziert na.locf mit einem na.rm = TRUE Argument, um na.rm = FALSE behavior zu erhalten, müssen wir einfach sicherstellen, dass das erste Element in cummax TRUE ist:

%Vor%

In diesem Fall müssen wir nicht nur die Nicht- NA -Indizes berücksichtigen, sondern auch die Indizes, bei denen die (geordnete oder anzuordnende) "id" -Spalte den Wert ändert:

%Vor%

Kombinieren Sie die obigen:

%Vor%

Beachten Sie, dass wir hier OR das erste Element mit TRUE bilden, d. h. es zu TRUE machen, wodurch das Verhalten na.rm = FALSE erhalten wird.

Und für dieses Beispiel:

%Vor%     
alexis_laz 06.05.2016, 09:16
quelle

Tags und Links