SAS中文论坛

标题: 关于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&#46;;
  format date yymmdd10&#46;;
  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=&#46;;
  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&#40;id&#41; or  code ne lag&#40;code&#41; or date ne lag&#40;date&#41; 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&#46;;
by id;
lag_date=lag&#40;date&#41;;
if code='A' and lag&#40;code&#41;='B'  then duration=lag_date-date;
drop lag_date;
run;

proc sort data=tem;by id date;run;[/code:766c4]
作者: shiyiming    时间: 2004-5-28 22:59
willon就是牛!
作者: shiyiming    时间: 2004-5-29 20:22
谢谢gbt 和willon的大力帮助!




欢迎光临 SAS中文论坛 (http://mysas.net/forum/) Powered by Discuz! X3.2