Locf eficiente por grupos en una sola tabla de datos R.
Tengo un gran, ampliodata.table
(20 millones de filas) con una ID de persona pero con muchas columnas (~ 150) que tienen muchos valores nulos. Cada columna es un estado / atributo registrado que deseo llevar a cabo para cada persona. Cada persona puede tener entre 10 y 10,000 observaciones y hay alrededor de 500,000 personas en el conjunto. Los valores de una persona no pueden "sangrar" en la siguiente persona, por lo que mi solución debe respetar la columna de ID de persona y agruparla adecuadamente.
Para fines de demostración, aquí hay una entrada de muestra muy pequeña:
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)
)
Se parece a esto:
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
Mi salida esperada se ve así:
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
He encontrado undata.table
solución que funciona, pero es terriblemente lenta en mis grandes conjuntos de datos:
DT[, na.locf(.SD, na.rm=FALSE), by=id]
He encontrado soluciones equivalentes usando dplyr que son igualmente lentas.
GRP = DT %>% group_by(id)
data.table(GRP %>% mutate_each(funs(blah=na.locf(., na.rm=FALSE))))
Tenía la esperanza de poder llegar a una 'auto' combinación con eldata.table
funcionalidad, pero parece que no puedo hacerlo bien (sospecho que necesitaría usar.N
pero simplemente no lo he descubierto).
En este punto, creo que tendré que escribir algo en Rcpp para aplicar eficientemente el locf agrupado.
Soy nuevo en R, pero no soy nuevo en C ++, así que estoy seguro de que puedo hacerlo. Siento que debería haber una manera eficiente de hacer esto en R usandodata.table
.