按日期/时间条件按组替换缺失值

时间:2018-02-09 21:09:50

标签: r dplyr

我希望按persondate1进行分组,并按人和日填写date2indicator的缺失数据 IF >在同一天发生下一次观察。

例如,person 1缺少第二次和第三次观察的date2indicator值。如下所示,我希望将此缺失值替换为此人当天中的下一次非NA观察:date2==2018-02-02 15:04:00indicator==1。< / p>

请注意,对于person 2,最后一个NA在同一天没有下一个观察结果,因此需要保留NA

这是我的数据框:

  person               date1               date2 indicator
1      1 2018-02-02 12:00:00 2018-02-02 12:05:00         1
2      1 2018-02-02 13:00:00                <NA>        NA
3      1 2018-02-02 14:00:00                <NA>        NA
4      1 2018-02-02 15:00:00 2018-02-02 15:04:00         1
5      2 2018-02-01 12:00:00                <NA>        NA
6      2 2018-02-01 13:00:00 2018-02-01 13:06:00         1
7      2 2018-02-02 12:00:00 2018-02-02 12:03:00         1
8      2 2018-02-03 12:00:00                <NA>        NA

这是我想要的数据框:

  person               date1               date2 indicator
1      1 2018-02-02 12:00:00 2018-02-02 12:05:00         1
2      1 2018-02-02 13:00:00 2018-02-02 15:04:00         1
3      1 2018-02-02 14:00:00 2018-02-02 15:04:00         1
4      1 2018-02-02 15:00:00 2018-02-02 15:04:00         1
5      2 2018-02-01 12:00:00 2018-02-01 13:06:00         1
6      2 2018-02-01 13:00:00 2018-02-01 13:06:00         1
7      2 2018-02-02 12:00:00 2018-02-02 12:03:00         1
8      2 2018-02-03 12:00:00                <NA>        NA

示例:

library(tidyverse)
df.have <- data.frame(person=c(1, 1, 1, 1, 2, 2, 2, 2),
                      date1=ymd_hms(c("2018-02-02 12:00:00", 
                                      "2018-02-02 13:00:00", 
                                      "2018-02-02 14:00:00", 
                                      "2018-02-02 15:00:00",
                                      "2018-02-01 12:00:00", 
                                      "2018-02-01 13:00:00", 
                                      "2018-02-02 12:00:00", 
                                      "2018-02-03 12:00:00")),
                       date2=ymd_hms(c("2018-02-02 12:05:00", 
                                       NA, 
                                       NA, 
                                       "2018-02-02 15:04:00",
                                       NA, 
                                       "2018-02-01 13:06:00", 
                                       "2018-02-02 12:03:00", 
                                       NA)),
                       indicator=c(1, NA, NA, 1,
                                   NA, 1, 1, NA))

df.want <- data.frame(person=c(1, 1, 1, 1, 2, 2, 2, 2),
                      date1=ymd_hms(c("2018-02-02 12:00:00", 
                                      "2018-02-02 13:00:00", 
                                      "2018-02-02 14:00:00", 
                                      "2018-02-02 15:00:00",
                                      "2018-02-01 12:00:00", 
                                      "2018-02-01 13:00:00", 
                                      "2018-02-02 12:00:00", 
                                      "2018-02-03 12:00:00")),
                      date2=ymd_hms(c("2018-02-02 12:05:00", 
                                      "2018-02-02 15:04:00",
                                      "2018-02-02 15:04:00", 
                                      "2018-02-02 15:04:00",
                                      "2018-02-01 13:06:00", 
                                      "2018-02-01 13:06:00", 
                                      "2018-02-02 12:03:00", 
                                      NA)),
                      indicator=c(1, 1, 1, 1,
                                  1, 1, 1, NA))

我可以过滤到一些替换值,但仍然可以从我想要的位置获得一些好处。

df.have %>%
  group_by(person, date(date1)) %>%
  arrange(person, date1) %>%
  filter(row_number() %in% c(n()))

1 个答案:

答案 0 :(得分:2)

您可以这样做(请注意,您还需要lubridate以及tidyverse套餐)...

df.want <- df.have %>% mutate(day=date(date1)) %>% #add a date variable for grouping
                       group_by(day,person) %>% 
                       fill(date2,indicator,.direction = "up") %>% #use tidyr 'fill' to remove NAs
                       ungroup() %>% 
                       select(-day) %>% #remove grouping variable
                       arrange(person,date1) #restore original order

df.want

# A tibble: 8 x 4
  person               date1               date2 indicator
   <dbl>              <dttm>              <dttm>     <dbl>
1      1 2018-02-02 12:00:00 2018-02-02 12:05:00         1
2      1 2018-02-02 13:00:00 2018-02-02 15:04:00         1
3      1 2018-02-02 14:00:00 2018-02-02 15:04:00         1
4      1 2018-02-02 15:00:00 2018-02-02 15:04:00         1
5      2 2018-02-01 12:00:00 2018-02-01 13:06:00         1
6      2 2018-02-01 13:00:00 2018-02-01 13:06:00         1
7      2 2018-02-02 12:00:00 2018-02-02 12:03:00         1
8      2 2018-02-03 12:00:00                  NA        NA