繁体   English   中英

SAS-识别前三年

[英]SAS-identifying three preceding years

我使用以下代码来识别和输出前三年。 为了提供更多详细信息,样本包括多个 Person ID,每个 Person ID 都有多年的观察结果。 最终样本将只保留至少有三年前的个人 ID(例如 2001 2002 2003)。

data have3 ;
  set have2;
  by personid;
  set have2 ( firstobs = 2 keep = year rename = (year = _year2) )

      have2 (      obs = 1 drop = _all_                        );

  _year2 = ifn(  last.personid, (.), _year2 ); /*output the value of next year*/

  set have2 ( firstobs = 3 keep = year rename = (year = _year3) )

      have2 (      obs = 2 drop = _all_                        );

  _year3 = ifn(  last.personid, (.), _year3 );  /*output the value of the year after the next year*/

  _prev1 = ifn( first.personid, (.), lag(year) ); /*output the value of previous year*/

  _prev2 = ifn( first.personid, (.), lag2(year) );/*output the value of the year before the previous year*/


  if (year-2 eq _prev1-1 eq _prev2) or

     (year+2 eq _year2+1 eq _year3) or

     (year eq _year2-1 eq _prev1+1) then output;

run;

这段代码在大多数情况下都很好。 但是,我的样本有一些棘手的情况。 下图显示了其中一种情况。 个人 ID 488 只有两个观察结果(1994 年和 1995 年)。 不幸的是,下一个 Person ID 489 的第一年是 1996。因此,ID488 Year1994 的 _year3 是 1996,这使得year+2 eq _year2+1 eq _year3变为真。 结果,ID488 Year1994 也输出到最终样本。 我怎样才能改进代码以避免这种情况? 谢谢!

在此处输入图片说明

在您的前瞻 SET 语句中保留 id 变量可能会更容易。

set have2(firstobs=2 keep=personid year rename=(personid=personid2 year=_year2))...
set have2(firstobs=3 keep=personid year rename=(personid=personid3 year=_year3))...

然后您可以确保下一个和下一个下一个记录实际上是针对同一个 PERSONID。

if personid ne personid2 then _year2=.;
if personid ne personid3 then _year3=.;

回溯变量也是如此。

_prev1=lag(year);
_prev2=lag2(year);
if personid ne lag(personid) then _prev1=.;
if personid ne lag2(personid) then _prev2=.;

SQL 查询可能更清楚:

%* group has at least 3 years;
create table want as
select *
from have
group by id
having count(distinct year) >= 3

DOW 循环可以计算一个状态变量,该变量表明该组在某处运行了 3 年

%* group has a run of 3 years somewhere in time;
data want;
  do _n_ = 1 by 1 until (last.id);
    set have;
    by id;
    if _n_ >= 3 and lag2(year)+1 = lag(year) and lag(year)+1 = year then 
      _group_has_3_consective_years = 1;
  end;

  do _n_ = 1 to _n_;
    set have;
    if _group_has_3_consective_years then OUTPUT;
  end;

  drop _:;
run;

DOW 循环还可以为更复杂的情况计算状态变量,这些情况需要来自具有 3 年运行时间的组的数据,该组在该组的最后一年结束。

%* group has a run of 3 years finishing at end time;
data want_3_ending;
  do _n_ = 1 by 1 until (last.id);
    set have;
    by id;
    if _n_ >= 3 and lag2(year)+1 = lag(year) and lag(year)+1 = year then do;
      _group_has_3_consective_years = 1;
      _end_at_year = year;
    end;
  end;

  _top_year = year;

  do _n_ = 1 to _n_;
    set have;
    if _group_has_3_consective_years and _end_at_year = _top_year then OUTPUT;
  end;

  drop _:;
run;

注意: LAG调用总是被解决,因为 SAS if语句执行快捷逻辑评估。 _N_ >= 3确保滞后都来自同一组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM