如何检查连续性,注意日期之间可能存在的差距

时间:2019-01-21 10:55:25

标签: r date group-by

我有一个包含日期的大数据框,需要连续检查第一个日期,如下所示:

ID   ID_2  END         BEG
1    55    2017-06-30  2016-01-01
1    55    2015-12-31  2015-11-12  --> Gap (required date)
1    88    2008-07-26  2003-02-24
2    19    2014-09-30  2013-05-01
2    33    2013-04-30  2011-01-01  --> Not Gap (overlapping)
2    19    2012-12-31  2011-01-01
2    33    2010-12-31  2008-01-01
2    19    2007-12-31  2006-01-01
2    19    2005-12-31  1980-10-20  --> No actual Gap(required date)

如图所示,并非所有日期都重叠,因此我需要按ID(不是ID_2)返回出现第一个间隔(时间倒退)的日期。我试过使用for,但是它非常慢(数据帧有15万行)。我一直在搞怪dplyr和mutate,如下所示:

df <- df%>%
  group_by(ID)%>%
  mutate(END_lead = lead(END))

df$FLAG <- df$BEG - days(1) == df$END_lead

df <- df%>%
 group_by(ID)%>%
 filter(cumsum(cumsum(FLAG == FALSE))<=1)

但是这组指令在第一个重叠处停止,过滤了错误的日期。我已经尝试过我能想到的一切,以降序或升序排序,并使用min和max,但找不到解决方案。

所需的实际结果是:

ID   ID_2  END         BEG
1    55    2015-12-31  2015-11-12 
2    19    2008-07-26  1980-10-20 

是否可以使用dplyr,tidyr和lubridate做到这一点?

2 个答案:

答案 0 :(得分:1)

使用dplyr的可能解决方案:

library(dplyr)

df %>%
  mutate_at(vars(END, BEG), funs(as.Date)) %>%
  group_by(ID) %>%
  slice(which.max(BEG > ( lead(END) + 1 ) | is.na(BEG > ( lead(END) + 1 ))))

使用您的最新数据,它会给出:

# A tibble: 2 x 4
# Groups:   ID [2]
     ID  ID_2 END        BEG       
  <int> <int> <date>     <date>    
1     1    55 2015-12-31 2015-11-12
2     2    19 2005-12-31 1980-10-20

该解决方案的作用基本上是:

  • 将日期更改为Date格式(不需要lubridate);
  • ID分组;
  • 选择满足条件的最高行,即最高行或者是一个空格(TRUE),或者如果没有空格,则它是第一行(这意味着在检查时缺少值)差距,这就是is.na(BEG > ( lead(END) + 1 )))的原因。

答案 1 :(得分:0)

我会使用xts包,首先为您拥有的每个ID创建xts对象,而不是对每个对象使用first()和last()函数。

https://www.datacamp.com/community/blog/r-xts-cheat-sheet