首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SAS-确定前三年

SAS-确定前三年
EN

Stack Overflow用户
提问于 2020-02-01 21:40:48
回答 2查看 39关注 0票数 0

我使用下面的代码来识别和输出前三年。为了提供更多的细节,样本包括多个人ID和每个人ID在多年内的观察结果。最后的样本只保留至少有前三年(如2001年、2002年、2003年)的个人身份证。

代码语言:javascript
复制
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;

这段代码在大多数情况下都很好。然而,我的样本有一些棘手的情况。下图显示了其中一种情况。第488号个人身份证只有两项观察(1994年和1995年)。不幸的是,下一个人身份证489的第一年是1996年。因此,_year3 of ID488 Year1994是使year+2 eq _year2+1 eq _year3成为现实的1996年。结果,ID488 Year1994也输出到最后的示例。如何改进代码以避免这种情况?谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-01 22:05:18

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

代码语言:javascript
复制
set have2(firstobs=2 keep=personid year rename=(personid=personid2 year=_year2))...
set have2(firstobs=3 keep=personid year rename=(personid=personid3 year=_year3))...

然后,您可以确保下一个和下一个-下一个记录实际上是为同一个人。

代码语言:javascript
复制
if personid ne personid2 then _year2=.;
if personid ne personid3 then _year3=.;

你的回溯变量也是一样的。

代码语言:javascript
复制
_prev1=lag(year);
_prev2=lag2(year);
if personid ne lag(personid) then _prev1=.;
if personid ne lag2(personid) then _prev2=.;
票数 1
EN

Stack Overflow用户

发布于 2020-02-02 11:21:49

SQL查询可能更清楚:

代码语言:javascript
复制
%* group has at least 3 years;
create table want as
select *
from have
group by id
having count(distinct year) >= 3

道氏圈可以计算一个状态变量,该变量表示该组在某个时间内运行了3年。

代码语言:javascript
复制
%* 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;

道氏循环还可以计算出更复杂的情况下的状态变量,即希望从运行3年的组中获得数据,这些数据在组的最后一年结束。

代码语言:javascript
复制
%* 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确保延迟都来自同一组。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60021313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档