Ich habe eine große, breite data.table
(20m Reihen) von einer Person ID aber mit vielen Spalten (~ 150), die viele Null-Werte 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 Spalte ID der Personenkennung und die Gruppe entsprechend berücksichtigen.effizient locf nach Gruppen in einem einzigen R data.table
Zu Demonstrationszwecken - hier ist eine sehr kleine Probeneingang:
DT = data.table(
id=c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3),
aa=c("A", NA, "B", "C", NA, NA, "D", "E", "F", NA, NA, NA),
bb=c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
cc=c(1, NA, NA, NA, NA, 4, NA, 5, 6, NA, 7, NA)
)
Es sieht wie folgt aus:
id aa bb cc
1: 1 A NA 1
2: 1 NA NA NA
3: 1 B NA NA
4: 1 C NA NA
5: 2 NA NA NA
6: 2 NA NA 4
7: 2 D NA NA
8: 2 E NA 5
9: 3 F NA 6
10: 3 NA NA NA
11: 3 NA NA 7
12: 3 NA NA NA
Meine erwartete Ausgabe sieht wie folgt aus:
id aa bb cc
1: 1 A NA 1
2: 1 A NA 1
3: 1 B NA 1
4: 1 C NA 1
5: 2 NA NA NA
6: 2 NA NA 4
7: 2 D NA 4
8: 2 E NA 5
9: 3 F NA 6
10: 3 F NA 6
11: 3 F NA 7
12: 3 F NA 7
I‘ Ich habe eine data.table
Lösung gefunden, die funktioniert, aber es ist schrecklich langsam auf meinen großen Datensätzen:
DT[, na.locf(.SD, na.rm=FALSE), by=id]
Ich habe gleichwertige Lösungen mit dplyr gefunden, die gleichermaßen langsam sind.
GRP = DT %>% group_by(id)
data.table(GRP %>% mutate_each(funs(blah=na.locf(., na.rm=FALSE))))
Ich war zuversichtlich, dass ich mit einem Roll ‚Selbst‘ kommen könnte kommen die data.table
-Funktionalität, aber ich kann es einfach nicht richtig zu machen scheint (ich vermute, ich würde .N
verwenden müssen, aber ich nur habe es nicht herausgefunden).
An diesem Punkt denke ich, dass ich etwas in Rcpp schreiben muss, um den gruppierten locf effizient anzuwenden.
Ich bin neu in R, aber ich bin nicht neu in C++ - also bin ich zuversichtlich, dass ich es schaffen kann. Ich habe einfach das Gefühl, dass es einen effizienten Weg geben sollte, dies in R mit data.table
zu tun.
x = c(1, NA, NA, 6, 4, 5, 4, NA, NA, 2)
x[cummax((!is.na(x)) * seq_along(x))]
# [1] 1 1 1 6 4 5 4 4 4 2
Dies repliziert na.locf
mit einem na.rm = TRUE
Argument, na.rm = FALSE
Verhalten zu bekommen, müssen wir einfach:
Ich bin mir ziemlich sicher, dass 'DT [, lapply (.SD, na.locf, F), durch = id]' wird schneller sein – eddi
ich damit tatsächlich begonnen und fand die Leistung schlechter. –
Rolling Self Join scheint hier ein Punkt zu sein, ich erinnere mich an einige Fragen, die sowohl 'na.locf'- als auch Rolling-Joins-Antworten haben, also denke ich, dass Sie die Antwort in der aktuellen SO-Wissensdatenbank finden können. – jangorecki