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:
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.
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:
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:
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:
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%Tags und Links r data.table dplyr dataframe rcpp