找到日期差异

4

我有以下数据:

ID GROUP     DATE 
A   GR1   12/01/2013
A   GR1   09/04/2014
A   GR1   01/03/2015
A   GR2   04/04/2015
A   GR2   08/21/2015
A   GR1   01/05/2016
A   GR1   06/28/2016
B   GR2   11/01/2013
B   GR2   06/04/2014
B   GR2   04/15/2015
B   GR3   11/04/2015
B   GR2   03/21/2016
B   GR2   07/05/2016
B   GR1   06/28/2016
C   GR2   01/16/2014
C   GR2   06/04/2014
C   GR2   04/15/2015
C   GR3   11/04/2015
C   GR2   03/21/2016
C   GR2   06/05/2016
C   GR1   06/28/2016

我希望得到每个组中人员留存率的差异。因此,新表格应如下所示:

ID GROUP     DATE      Diff
A   GR1   12/01/2013
A   GR1   09/04/2014
A   GR1   01/03/2015    398
A   GR2   04/04/2015
A   GR2   08/21/2015    139
A   GR1   01/05/2016
A   GR1   06/28/2016    175
B   GR2   11/01/2013
B   GR2   06/04/2014
B   GR2   04/15/2015    530
B   GR3   11/04/2015
B   GR2   03/21/2016
B   GR2   07/05/2016    106
B   GR1   06/28/2016
C   GR2   01/16/2014
C   GR2   06/04/2014    
C   GR2   04/15/2015    454
C   GR3   11/04/2015
C   GR2   03/21/2016
C   GR2   01/05/2016    76
C   GR1   06/28/2016

“Diff”列中的值398是通过计算‘01/03/2015’- ‘12/1/2013’得出的差异。类似地,其他所有差异也是这样得出的。

现在我的问题是如何获得这个差异?我不能在每个组中取max(date)-min(date),因为不同时间段会重复出现相同的组。同样,我也不能像SAS那样取第一个点和最后一个点。

如果有人能帮我解决这个问题,我将非常感激。由于数据量非常大,因此我更喜欢使用SAS来解决这个问题。所以无法将其全部保存在内存中。

谢谢!

3个回答

6
library(dplyr)
library(data.table)
df$xxx = rleidv(df[, c("ID","GROUP"),with = FALSE ])
df$DATE = as.Date(df$DATE, format = "%m/%d/%Y")
df %>% group_by(xxx) %>% mutate(diff = max(DATE) - min(DATE)) %>%
       ungroup(xxx) %>% mutate(xxx = NULL)
#     ID GROUP       DATE     diff
#   <chr> <chr>     <date>   <time>
#1      A   GR1 2013-12-01 398 days
#2      A   GR1 2014-09-04 398 days
#3      A   GR1 2015-01-03 398 days
#4      A   GR2 2015-04-04 139 days
#5      A   GR2 2015-08-21 139 days
#6      A   GR1 2016-01-05 175 days
#7      A   GR1 2016-06-28 175 days
#8      B   GR2 2013-11-01 530 days
#9      B   GR2 2014-06-04 530 days
#10     B   GR2 2015-04-15 530 days

仅使用 data.table

library(data.table)
df[, diff := max(DATE)-min(DATE),by = c("xxx")][,xxx:=NULL]

5

使用SAS很容易实现。使用RETAIN保留组中第一条记录的开始日期。由于您的数据未排序,因此可以先对其进行排序,或者如果想保留当前顺序(并且组内记录已按日期排序),则可以在BY语句上使用NOTSORTED选项。

data want ;
  set have ;
  by id group notsorted;
  if first.group then start = date ;
  else if last.group then diff = date - start ;
  retain start;
  drop start;
run;

如果您需要保留当前的顺序,但是日期在组内没有排序,则需要添加另一个变量和一些逻辑来查找组内的最小和最大日期。

data want ;
  set have ;
  by id group notsorted;
  if first.group then start = date ;
  if first.group then stop = date ;
  start = min(start,date);
  stop = max(stop,date);
  if last.group and not first.group then diff = stop - start ;
  retain start stop;
  drop start stop;
run;

2
data want(drop=_:);
   merge have have(firstobs=2 rename=(id=_id group=_group date=_date));
   retain _temp;
   _temp= min(_temp,date);
   if id^=_id or group^=_group then do;
       diff=intck('day',_temp,date);
       if diff=0 then call missing(diff);
       _temp=_date;
   end;
run;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接