Bir kullanıcı kimliği ile anahtarlanmış, ancak çok sayıda null değere sahip çok sayıda sütun (~ 150) içeren geniş, geniş data.table
(20m satır) var. Her sütun, her bir kişi için ileriye taşımak istediğim kayıtlı bir durum/özelliktir. Her bir kişi 10 ila 10,000 gözlemden herhangi birine sahip olabilir ve sette yaklaşık 500.000 kişi var. Bir kişiden elde edilen değerler aşağıdaki kişiye 'kanama' yapamaz, bu yüzden çözümüm kişinin kimlik sütununa ve gruba uygun şekilde saygı göstermelidir.Tek bir R data.table içinde grupların verimli bir şekilde konumlandırılabilir
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)
)
Bu şuna benzer: - Gösteri amaçlı
burada çok küçük bir örnek girdi var
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
My beklenen çıkışı şöyle görünür:
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
Ben ve çalıştığı bir data.table
çözüm buldu, ancak büyük veri kümelerimde çok yavaş:
DT[, na.locf(.SD, na.rm=FALSE), by=id]
Eşit derecede yavaş olan dplyr kullanarak eşdeğer çözümler buldum.
GRP = DT %>% group_by(id)
data.table(GRP %>% mutate_each(funs(blah=na.locf(., na.rm=FALSE))))
ben ben .N
kullanmak gerekir şüpheli ama sadece ben (yuvarlanan 'öz' ile gelip data.table
işlevini kullanarak katılmak, ama sadece doğru olsun gibi olamaz ki ümitli olduğunu bunu anlamadım).
Bu noktada, gruplandırılmış locayı verimli bir şekilde uygulamak için Rcpp'de bir şeyler yazmam gerektiğini düşünüyorum.
R için yeniyim, fakat C++ için yeni değilim - bu yüzden yapabilirim. Sadece data.table
kullanarak R'de bunu yapmak için verimli bir yol olmalı.
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
Bu biz sadece ihtiyaç na.rm = FALSE
davranışı elde etmek, bir na.rm = TRUE
argümanla na.locf
çoğaltır:
ben [= id tarafından, lapply (.SD, na.locf F)] DT 'eminim' hızlı olacaktır Aslında o ile başladı – eddi
ve performansın daha kötü olduğu ortaya çıktı. –
Rolling self join burada noktaya bakar gibi görünüyor, hem 'na.locf' hem de haddeleme birleştirme cevapları var bazı soruları hatırlıyorum, bu yüzden mevcut SO bilgi tabanında cevap bulabilirsiniz düşünüyorum. – jangorecki