[英]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.