locf de forma eficiente por grupos em um único data.table R
Eu tenho uma grande, largadata.table
(20m linhas) codificadas por um ID de pessoa, mas com muitas colunas (~ 150) que possuem muitos valores nulos. Cada coluna é um estado / atributo gravado que desejo levar adiante para cada pessoa. Cada pessoa pode ter de 10 a 10.000 observações e existem cerca de 500.000 pessoas no conjunto. Os valores de uma pessoa não podem "sangrar" para a pessoa a seguir; portanto, minha solução deve respeitar a coluna e o grupo de identificação da pessoa adequadamente.
Para fins de demonstração - aqui está uma pequena amostra de entrada:
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 com isso:
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
Minha saída esperada é assim:
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
Eu encontrei umdata.table
solução que funciona, mas é muito lenta nos meus grandes conjuntos de dados:
DT[, na.locf(.SD, na.rm=FALSE), by=id]
Encontrei soluções equivalentes usando o dplyr que são igualmente lentas.
GRP = DT %>% group_by(id)
data.table(GRP %>% mutate_each(funs(blah=na.locf(., na.rm=FALSE))))
Eu esperava que eu pudesse criar uma junção 'self' rolante usando odata.table
funcionalidade, mas não consigo acertar (suspeito que precisaria usar.N
mas eu ainda não descobri).
Neste ponto, estou pensando que terei que escrever algo no Rcpp para aplicar eficientemente o locf agrupado.
Sou novo em R, mas não sou novo em C ++ - por isso estou confiante de que posso fazê-lo. Eu apenas sinto que deve haver uma maneira eficiente de fazer isso em R usandodata.table
.