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
语句,我们还可以添加 first
和 last
来让您确定您在组中的位置。这假设它已经排序 by group
.
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;
这和以前做同样的事情——将以前的值与当前值进行比较——但是让它更容易看,我们添加了一个选项来在 [=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 ].
考虑以下形式的数据集 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
语句,我们还可以添加 first
和 last
来让您确定您在组中的位置。这假设它已经排序 by group
.
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;
这和以前做同样的事情——将以前的值与当前值进行比较——但是让它更容易看,我们添加了一个选项来在 [=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 ].