考虑 test
以下形式的数据集:
Group Date
1 05JAN2014
1 08JAN2014
1 14JAN2014
2 05JAN2013
2 10FEB2015
2 27FEB2015
Run Code Online (Sandbox Code Playgroud)
我想根据小组计算日期的差异.以下代码记录了每两个日期之间的差异:
data test;
datediff = dif(Date);
run;
Run Code Online (Sandbox Code Playgroud)
我如何只考虑一组中日期之间的差异?此外,有没有办法区分每组的最后和第一个日期?
从这开始:
data test;
datediff = dif(Date);
run;
Run Code Online (Sandbox Code Playgroud)
让我们一次一个地解决你的问题.首先,添加一个set
语句和一个by
语句,我们还可以添加first
并last
允许您确定您在组中的位置.这假定它已经排序了by group
.
data test2;
set test;
by group;
datediff=dif(date);
run;
Run Code Online (Sandbox Code Playgroud)
这没有任何不同(假设你最初有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;
Run Code Online (Sandbox Code Playgroud)
这与以前的做法相同 - 将前一个值与当前值进行比较 - 但使其更容易看到,并且我们添加了一个选项,以便last_date
在first.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;
Run Code Online (Sandbox Code Playgroud)
现在我们做了和以前一样的事情 - 但是每当我们看到first.group
并计算group_datediff时,我们就会重置orig_date last.group
.