标题: 关于lag的疑问 [打印本页] 作者: shiyiming 时间: 2004-5-28 13:49 标题: 关于lag的疑问 数据格式如下:
id code date
1 A 2003-04-16
1 B 2003-04-29
2 A 2003-05-12
2 B 2003-06-01
2 C 2003-06-12
3...
我按照ID 和DATE排序后,需要找到每一个不同ID在CODE下出现的相邻的A B取值,而且在CODE 取A的纪录后增加一个字段 DURATION=B的DATE值-A的DATE值.结果如下:
id code date duration
1 A 2003-04-16 13 = [(2003-04-29)-(2003-04-16)]
1 B 2003-04-29
2 A 2003-05-12
2 B 2003-06-01 20
2 C 2003-06-12
3...
我用lag函数是这样写的
[code:3dd56]data b;
set a(原数据集);
by id;
if code='B' and lag(code)='A' then duration=date-lag(date);
run;[/code:3dd56]
这样首先是duration的值是增加在code取B的记录后面,而且log(date)的取值我发现还不对,它取了满足if 条件的前一个纪录date的值。
请各位高手帮帮忙,多谢?作者: shiyiming 时间: 2004-5-28 20:33
lag函数的返回值不总是set 数据集中的上一个记录,它的明确的定义应是一个队列中的上一个记录,队列的范围就不好说了,比如你所遇到的情况。具体的可以参照sas在线帮助文档 <!-- m --><a class="postlink" href="http://v8doc.sas.com/sashtml">http://v8doc.sas.com/sashtml</a><!-- m --> 。我写了一个程序,很繁琐,不过可以达到你的最初的要求
[code:5351e]data tem;
input id code$ date yymmdd10.;
format date yymmdd10.;
cards;
1 A 2003-04-16
1 B 2003-04-29
2 A 2003-05-12
2 B 2003-06-01
2 C 2003-06-12
;
data a;
set tem;
retain idp codep datep;
if code='A' then do;
idp=id;
codep=code;
datep=date;
output;
end;
else do;
output;
if code='B' and codep='A' then do;
duration=date-datep;
id=idp;
code=codep;
date=datep;
output;
end;
codep=.;
end;
drop idp codep datep;
proc sort data=a;
by id date code descending duration;
data c;
set a;
by id date code;
if id ne lag(id) or code ne lag(code) or date ne lag(date) then output;
run;[/code:5351e]作者: shiyiming 时间: 2004-5-28 21:15
我还没有查lag的运行机制,但是凭经验,不要在判断语句的执行部分使用lag,否则会有问题。
既然只有lag1(),而没有lag-1(),在这个问题上date字段降序排序比使用升序更容易解决。
[code:766c4]proc sort data=tem;by id descending date;run;
data tem;
set tem;
format lag_date yymmdd10.;
by id;
lag_date=lag(date);
if code='A' and lag(code)='B' then duration=lag_date-date;
drop lag_date;
run;