【发布时间】:2018-10-06 13:45:09
【问题描述】:
我正在寻找一种方法来有条件地使用 fill() 命令或类似的东西来根据前一行值填充 NA 值,前提是满足条件。我一直在寻找解决方案,但无法得到我发现的任何东西。
数据如下所示,但有多个“caseval”测量值:
casedate = seq(as.Date('2018/1/1'),as.Date('2018/3/5'),b='week')
caseid = c(rep(1,10),rep(2,10),rep(3,10))
caseval = c(80,rep(NA,4),rep(80,5),40,rep(NA,2),rep(40,4),rep(50,3),rep(NA,7),rep(70,3))
df = cbind.data.frame(casedate,caseid, caseval)
每条记录代表一个日期和一个测量值。对于某些项目,测量在没有变化时被跳过,对于其他项目,在日期没有相关的测量(由该 caseid 的第一个记录表示为 NA),如下面的第 21 行。使用不带条件的填充时,第 21:27 行将填充 caseid 2 的值,这是不正确的。
casedate caseid caseval
1 2018-01-01 1 80
2 2018-01-08 1 NA
3 2018-01-15 1 NA
4 2018-01-22 1 NA
5 2018-01-29 1 NA
6 2018-02-05 1 80
7 2018-02-12 1 80
8 2018-02-19 1 80
9 2018-02-26 1 80
10 2018-03-05 1 80
11 2018-01-01 2 40
12 2018-01-08 2 NA
13 2018-01-15 2 NA
14 2018-01-22 2 40
15 2018-01-29 2 40
16 2018-02-05 2 40
17 2018-02-12 2 40
18 2018-02-19 2 50
19 2018-02-26 2 50
20 2018-03-05 2 50
**21 2018-01-01 3 NA**
22 2018-01-08 3 NA
23 2018-01-15 3 NA
24 2018-01-22 3 NA
25 2018-01-29 3 NA
26 2018-02-05 3 NA
27 2018-02-12 3 NA
28 2018-02-19 3 70
29 2018-02-26 3 70
30 2018-03-05 3 70
我尝试了一个循环,它可以工作,但是很慢
for (i in 1:nrow(df)) {
for (item in list_casevals) {
if (df[i,'caseid']==df[i-1,'caseid'] && is.na(df[i,item])) {
df[i,item]=df[i-1,item]
}
}
}
我已经尝试在 ifelse 中使用填充,但它只替换第 2 行中的 NA,而没有其他内容,除非它再次运行,当它替换第 3 行等时。
df = df %>%
mutate(., caseval = ifelse(lag(caseid)==caseid & is.na(caseval),fill(caseval),caseval))
除了使用循环之外,还有更快的方法吗?
【问题讨论】: