首页 > 解决方案 > 如何根据 2 列中的值给出的日期范围删除行?

问题描述

我有一个包含一系列日期的数据集,需要在新行中填写缺失的日期。df1是我正在使用的数据df2的一个例子,也是我设法实现的一个例子(我被困的地方)。df3是我想结束的地方!

df1
ID     Date       DateStart     DateEnd
1      2/11/2021  2/11/2021     2/17/2021
1      2/19/2021  2/19/2021     2/21/2021
2      1/15/2021  1/15/2021     1/20/2021  
2      1/22/2021  1/22/2021     1/23/2021  

这就是我所在的地方。NA 不是问题,因为我打算在完成我需要做的事情后删除 DateStart 和 DateEnd 列。这里的问题是我不想包含之前的 DateStart 和 DateEnd 范围内的日期。为了到达这里,我按 ID 分组并填写了以下日期之间的缺失日期df1

df2
ID     Date       DateStart     DateEnd
1      2/11/2021  2/11/2021     2/17/2021
1      2/12/2021  NA            NA
1      2/13/2021  NA            NA
1      2/14/2021  NA            NA
1      2/15/2021  NA            NA
1      2/16/2021  NA            NA
1      2/17/2021  NA            NA
1      2/18/2021  NA            NA
1      2/19/2021  2/19/2021     2/21/2021
2      1/15/2021  1/15/2021     1/20/2021
2      1/16/2021  NA            NA
2      1/17/2021  NA            NA
2      1/18/2021  NA            NA
2      1/19/2021  NA            NA
2      1/20/2021  NA            NA
2      1/21/2021  NA            NA
2      1/22/2021  NA            NA    
2      1/23/2021  1/23/2021     1/24/2021  

这实际上是我想要结束的:

df3
ID     Date       DateStart     DateEnd
1      2/11/2021  2/11/2021     2/17/2021
1      2/18/2021  NA            NA
1      2/19/2021  2/19/2021     2/21/2021
2      1/15/2021  1/15/2021     1/20/2021
2      1/21/2021  NA            NA
2      1/22/2021  NA            NA    
2      1/23/2021  1/23/2021     1/24/2021  

df3缺少的日期被填写但不是在 DateStart-DateEnd 范围内的日期。

关于如何实现这一目标的任何想法?注意:我有一个包含大量观察的数据集。

标签: rdaterangetidyversefill

解决方案


  • 将日期列转换为日期类。

  • 为每次ID使用complete创建从最小值DateStart到最大值的日期序列DateEnd

  • fillNA具有先前非 NA的值,除了 where Date > DateEnd

  • 对于每组 ID,DateStart并在每组中DateEnd保留具有NA值或行号 1 的行。

library(dplyr)
library(tidyr)

df %>%
  mutate(across(-ID, lubridate::mdy)) %>%
  group_by(ID) %>%
  complete(Date = seq(min(DateStart), max(DateEnd), by = '1 day')) %>%
  fill(DateStart, DateEnd) %>%
  ungroup %>%
  mutate(across(c(DateStart, DateEnd), ~replace(., Date > DateEnd, NA))) %>%
  group_by(ID, DateStart, DateEnd) %>%
  filter(is.na(DateStart) | row_number() == 1)

#     ID Date       DateStart  DateEnd   
#  <int> <date>     <date>     <date>    
#1     1 2021-02-11 2021-02-11 2021-02-17
#2     1 2021-02-18 NA         NA        
#3     1 2021-02-19 2021-02-19 2021-02-21
#4     2 2021-01-15 2021-01-15 2021-01-20
#5     2 2021-01-21 NA         NA        
#6     2 2021-01-22 NA         NA        
#7     2 2021-01-23 2021-01-23 2021-01-24

数据

df <- structure(list(ID = c(1L, 1L, 2L, 2L), Date = c("2/11/2021", 
"2/19/2021", "1/15/2021", "1/23/2021"), DateStart = c("2/11/2021", 
"2/19/2021", "1/15/2021", "1/23/2021"), DateEnd = c("2/17/2021", 
"2/21/2021", "1/20/2021", "1/24/2021")), 
class = "data.frame", row.names = c(NA, -4L))

推荐阅读