【问题标题】:use fill to conditionally fill NA values without loop使用 fill 有条件地填充 NA 值而无需循环
【发布时间】: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))

除了使用循环之外,还有更快的方法吗?

【问题讨论】:

    标签: r date dplyr tidyr


    【解决方案1】:

    您可以按caseid 分组吗?例如,

    df <- df %>%
      group_by(caseid) %>%
      fill(caseval) %>%
      ungroup()
    

    【讨论】:

    • 谢谢!在水平切片上测试,这似乎有效,但我从未以这种方式使用 group_by。你能解释一下这是如何/为什么起作用的吗?
    • group_by 的重点是使用分组变量对每个数据子集执行后续操作。这可能不是通常使用它的地方,但它当然值得一试……而且它奏效了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-23
    • 1970-01-01
    • 2012-03-21
    • 2015-02-06
    • 2021-10-21
    • 1970-01-01
    • 2018-01-01
    相关资源
    最近更新 更多