各组SAS中的日期差异

各组SAS中的日期差异,sas,Sas,考虑以下形式的数据集测试: Group Date 1 05JAN2014 1 08JAN2014 1 14JAN2014 2 05JAN2013 2 10FEB2015 2 27FEB2015 我想根据组计算日期的差异。以下代码表示每两个日期之间的差异: data test; datediff = dif(Date); run; 我如何只考虑一组中日期之间的差异?此外,是否有一种方法可以区分

考虑以下形式的数据集
测试

 Group   Date
  1      05JAN2014
  1      08JAN2014
  1      14JAN2014
  2      05JAN2013
  2      10FEB2015
  2      27FEB2015
我想根据组计算日期的差异。以下代码表示每两个日期之间的差异:

  data test;
  datediff = dif(Date);
  run;

我如何只考虑一组中日期之间的差异?此外,是否有一种方法可以区分各组最后一次和第一次的日期?

这里有一种方法,使用
lag
和新的
ifn
函数(
ifn
包含在SAS 9.2或更高版本中)。对滞后函数要小心一点,因为它有时会产生一些意想不到的结果。有关详细信息,请参阅

*Data must be sorted to use BY groups;
proc sort data=have; by group date;run;

data want;
    set have;
    by group;
    dateDiff = ifn(first.group, . , dif(date));

    retain firstDate;
    if first.group then firstDate = date;
    if last.group then dateDiff_all = date - firstDate;
run;

下面是一个使用proc sql和group by语句以及摘要函数min和max的解决方案

这将使您了解每组第一次和最后一次约会的差异

从技术上讲,它会让你得到最小和最大日期的差异,但你的日期是按时间顺序排列的,所以它会对这些数据起作用

proc sql;
    create table want as select
    group,
    max(date) - min(date) as datediff
    from have 
    group by group;
quit;
从这一点开始:

 data test;
  datediff = dif(Date);
  run;
让我们一次解决一个问题。首先,添加一个
set
语句和一个
by
语句,我们还可以添加
First
last
,以便您确定自己在组中的位置。这假设它已经按组进行了排序

data test2;
  set test;
  by group;
  datediff=dif(date);
run;
这并没有什么不同(无论如何,假设您最初有set语句)。但是现在,你有了一些新的选择

首先,虽然您可以使用
dif
,但我建议使用
retain
方法。您可以更容易地看到它在做什么,并避免一些常见的陷阱:特别是,
lag
dif
实际上并不与以前的记录进行比较-它们创建了一个队列并与之进行比较,这在使用条件语句时可能会导致复杂性

data test2;
  set test;
  by group;
  retain last_date;
  if first.group then last_date=0;
  datediff = date - last_date;
  output;
  last_date = date;
run;
这与之前的操作相同-将以前的值与当前值进行比较-但更容易查看,并且我们添加了一个选项,在
first.group
为true时重置
last\u date
变量-这意味着我们位于group的新值的第一行。我不会删除这些中间变量中的任何一个,但是在生产代码中,您可以而且应该删除它们
retain
表示该值将跨行保留(而不是在每次获得新行时重置)

现在有一个变量跟踪前一行的
date
值,我们很容易看到如何在第一个->最后一个差异中实现这一点

data test2;
  set test;
  by group;
  retain last_date orig_date;
  if first.group then do;
    last_date=0;
    orig_date=date;  **new;
  end;
  datediff = date - last_date; 
  if last.group then group_datediff = date-orig_date;  **new;
  output;
  last_date = date;
run;

现在我们做了和以前一样的事情-但是我们每次先看到
时都会重置原始日期。group
并在最后点击
时计算group\u datediff。group

您可以使用
dif
函数来计算datediff,而不是获取滞后日期并从当前日期中减去它(
dateDiff=ifn(first.group,,,dif(date));
Good think@Keith-被编辑得更加优雅:)@Joe这在我使用过的大多数SQL变体中都很有效(只是在mySQL和MSSQL中进行了测试,以确保我没有发疯)。我不确定你想说什么,因为选择与组匹配的是。。。(即select=group,group by=group)。嗯。我一定是误读了这个——最初我读的是select*.Oops。
data test2;
  set test;
  by group;
  datediff=dif(date);
run;