2017-10-16 78 views
1

我有一個相當大的數據框(70k×900),其中包含ID,日期和~900個代碼列。代碼缺失的地方,我想填補這些缺失的值。通過分組ID和日期有效地填充缺失值

規則是,對於每個包含未在以後的日期記錄的代碼的ID,它應該結轉。

我已經將我的數據框轉換爲寬格式(假設這是最簡單的方法來減少值)。

見例如DF:

df <- as.data.frame(list(
id = c('p1', 'p1', 'p1', 'p2', 'p2', 'p2'), 
date = as.Date(1:6, origin=Sys.Date()), 
code_1 = c('c_1', NA, NA, 'c_1', NA, NA), 
code_2 = c(NA, 'c_2', NA, NA, NA, NA), 
code_3 = c(NA, NA, 'c_3', NA, NA, NA))) 

我想返回類似以下,其中代碼依次填寫:

df2 <- as.data.frame(list(
id = c('p1', 'p1', 'p1', 'p2', 'p2', 'p2'), 
date = as.Date(1:6, origin=Sys.Date()), 
code_1 = c('c_1', 'c_1', 'c_1', 'c_1', 'c_1', 'c_1'), 
code_2 = c(NA, 'c_2', 'c_2', NA, NA, NA), 
code_3 = c(NA, NA, 'c_3', NA, NA, NA))) 

我曾嘗試以下:

df[, lapply(FUN = na.locf, na.rm = FALSE), by = .(id)] 

但是由於尺寸的原因,我的電腦無法處理,因此解決方案必須高效。

真的很感謝任何幫助。

+0

是唯一的每個ID代碼,即一旦P1在code_1已C_1可以將其在不同的代碼code_1以後? – kath

+1

您正試圖在dataframe上使用'data.table'語法,這是行不通的。使用'library(data.table); setDT(df)[,3:5:= lapply(.SD,na.locf,na.rm = FALSE),by = id,.SDcols = 3:5] []'應該完成這項工作。 – Jaap

+0

@kath感謝您的評論。這些代碼對於每個ID都不是唯一的,但是考慮到數據幀的構造,只有code_1會出現在code_1列中。我希望這是有道理的? – avocet

回答

0

您可以使用filltidyr

library(dplyr) 
library(tidyr) 
df %>% 
    group_by(id) %>% 
    fill(code_1:code_3) 

結果:

# A tibble: 6 x 5 
# Groups: id [2] 
     id  date code_1 code_2 code_3 
    <fctr>  <date> <fctr> <fctr> <fctr> 
1  p1 2017-10-17 c_1  NA  NA 
2  p1 2017-10-18 c_1 c_2  NA 
3  p1 2017-10-19 c_1 c_2 c_3 
4  p2 2017-10-20 c_1  NA  NA 
5  p2 2017-10-21 c_1  NA  NA 
6  p2 2017-10-22 c_1  NA  NA 
+1

偉大的解決方案,這工作完美。增加進度條的現有好處(數據量很大,所以這很有幫助)。謝謝! – avocet