SAS 中的日期差异(按组)

Difference in dates in SAS by group

考虑以下形式的数据集 test

 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 或更高版本中)。使用滞后函数时要小心,因为它有时会产生一些意想不到的结果。有关详细信息,请参阅 this paper

*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 和带有汇总函数 min 和 max 的 group by 语句的解决方案。

这将使您在第一天和最后一天的每组中有所不同。

从技术上讲,它会为您提供最小日期和最大日期的差异,但您的日期是按时间顺序排列的,因此它适用于此数据。

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 语句,我们还可以添加 firstlast 来让您确定您在组中的位置。这假设它已经排序 by group.

data test2;
  set test;
  by group;
  datediff=dif(date);
run;

这没有任何不同(假设您最初有 set 语句)。但是现在,你有了一些新的选择。

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

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;

这和以前做同样的事情——将以前的值与当前值进行比较——但是让它更容易看,我们添加了一个选项来在 [=24] 时重置 last_date 变量=] 为真 - 意味着我们在组的新值的第一行。我不会删除任何这些中间变量,但在生产代码中您可以而且应该删除。 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;

现在我们做了和以前一样的事情——但是我们在每次看到 first.group 时重置 orig_date 并在我们点击 [=28= 时计算 group_datediff ].