通过分组ID和日期有效地填充缺失值
问题描述:
我有一个相当大的数据框(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)]
但是由于尺寸的原因,我的电脑无法处理,因此解决方案必须高效。
真的很感谢任何帮助。
答
您可以使用fill
从tidyr
:
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
是唯一的每个ID代码,即一旦P1在code_1已C_1可以将其在不同的代码code_1以后? – kath
您正试图在dataframe上使用'data.table'语法,这是行不通的。使用'library(data.table); setDT(df)[,3:5:= lapply(.SD,na.locf,na.rm = FALSE),by = id,.SDcols = 3:5] []'应该完成这项工作。 – Jaap
@kath感谢您的评论。这些代码对于每个ID都不是唯一的,但是考虑到数据帧的构造,只有code_1会出现在code_1列中。我希望这是有道理的? – avocet