根据数据框中的开始/结束值填写NA值

时间:2018-03-23 20:08:31

标签: r dplyr tidyr

我目前有一个包含起始值和结束值的数据框。我需要它们在开始和结束值之间“填写”。警告:有许多值仍需要保持NA。

背景信息:我正在跟踪持续一定天数的事件。例如(见下文),一个事件可能会持续3天,或者可能会持续6个。另一方面,如果在一系列日期内没有事件,我需要保持NA。

以下是目前的情况:

Date        value event event_detail
2017-03-30  12    NA    NA
2017-03-31  14    NA    NA
2017-04-01  15    A     Y
2017-04-02  20    NA    NA
2017-04-03  17    A     Y
2017-04-04  20    NA    NA
2017-04-05  14    NA    NA

这就是我想要的:

Date        value event event_detail
2017-03-30  12    NA    NA
2017-03-31  14    NA    NA
2017-04-01  15    A     Y
2017-04-02  20    A     Y
2017-04-03  17    A     Y
2017-04-04  20    NA    NA
2017-04-05  14    NA    NA

棘手的情况是,在4月3日之后,可能会有一段时间没有事件,我不希望事件“A”或细节“Y”填写。

有什么想法吗?谢谢。

1 个答案:

答案 0 :(得分:0)

如果你的愿望只是向后传递一个值,那么zoo::na.locf()(最后一次观察前进)有一个选项可以做到这一点(基本上它会成为后面的观察结果)。

library(zoo)

mydata <- 
    data.frame(stringsAsFactors=FALSE,
               Date = c("1/04/2017", "2/04/2017", "3/04/2017", "4/04/2017",
                        "5/04/2017"),
               value = c(15L, 20L, 17L, 20L, 14L),
               event = c("A", NA, "A", NA, NA),
               event_detail = c("Y", NA, "Y", NA, NA)
               )

mydata$event <- na.locf(mydata$event, fromLast = TRUE, na.rm = FALSE)
mydata$event_detail <- na.locf(mydata$event_detail, fromLast = TRUE, na.rm = FALSE)

mydata

       Date value event event_detail
1 1/04/2017    15     A            Y
2 2/04/2017    20     A            Y
3 3/04/2017    17     A            Y
4 4/04/2017    20  <NA>         <NA>
5 5/04/2017    14  <NA>         <NA>

请记住在执行此操作之前对数据进行排序!

编辑:刚刚看到你有dplyr标签。就是这样:

mydata %<>%
    mutate_at(vars(starts_with("event")), na.locf, fromLast = TRUE, na.rm = FALSE)

如果您知道您的差距大小将小于观察之间的时段大小,您也可以限制na.locf的范围。

mydata <- 
    data.frame(stringsAsFactors=FALSE,
               Date = c("30/03/2017", "31/03/2017", "1/04/2017", "2/04/2017",
                        "3/04/2017", "4/04/2017", "5/04/2017"),
               value = c(12L, 14L, 15L, 20L, 17L, 20L, 14L),
               event = c(NA, NA, "A", NA, "A", NA, NA),
               event_detail = c(NA, NA, "Y", NA, "Y", NA, NA)
    )

mydata %<>%
    mutate_at(vars(starts_with("event")), na.locf, fromLast = TRUE, 
              na.rm = FALSE, maxgap = 1)

mydata

        Date value event event_detail
1 30/03/2017    12  <NA>         <NA>
2 31/03/2017    14  <NA>         <NA>
3  1/04/2017    15     A            Y
4  2/04/2017    20     A            Y
5  3/04/2017    17     A            Y
6  4/04/2017    20  <NA>         <NA>
7  5/04/2017    14  <NA>         <NA>