在 SAS 中使用 Panel 数据建立处理样本
Establishing treatment sample with Panel data in SAS
我有看起来像这样的面板数据:
ID year dummy
1234 2007 0
1234 2008 0
1234 2009 0
1234 2010 1
1234 2011 1
2345 2008 0
2345 2009 1
2345 2010 1
2345 2011 1
3456 2008 0
3456 2009 0
3456 2010 1
3456 2011 1
随着更多的观察结果遵循相同的模式以及更多与此问题无关的变量。
我想建立一个 ID 处理样本,其中虚拟变量 "switches" 在 2010 年(year<2010 时为 0,year>=2010 时为 1)。在上面的示例数据中,1234 和 3456 会在样本中,而 2345 不会。
我是 SAS 的新手,我想我对 CLASS 和 BY 语句还不够熟悉,无法弄清楚如何做到这一点。
到目前为止我已经这样做了:
data c_temp;
set c_data_full;
if year < 2010 and dummy=0
then trtmt_grp=1;
else pre_grp=0;
if year >=2010 and dummy=1
then trtmt_grp=1;
run;
但这对数据的面板方面没有任何作用。我不知道如何进行最后一步,即每年仅选择 trtmt_grp 为 1 的 ID。
感谢所有帮助!谢谢!
我想你可能想要一个双 DOW 循环。第一个循环在 ID 级别计算您的 TRTMT_GRP 标志,第二个循环计算 select 详细记录。
data want ;
do until (last.id);
set c_data_full;
by id dummy ;
if first.dummy and dummy=1 and year=2010 then trtmt_grp=1;
end;
do until (last.id);
set c_data_full;
by id ;
if trtmt_grp=1 then output;
end;
run;
不要认为您需要双 DoW 循环,除非您需要将数据附加到其他行。如果每个匹配的 ID 只需要一行,简单的单次传递就足够了。
data want;
set have;
by id;
retain grpcheck; *keep its value for multiple passes;
if first.id and year < 2010 then grpcheck=1; *reset for each ID to 1 (kept);
else if first.id and year ge 2010 then grpcheck=0;
if (year<2010) and (dummy=1) then grpcheck=0; *if a non-zero is found before 2010, set to 0;
if (year >= 2010) and (dummy=0) then grpcheck=0; *if a 0 is found at/after 2010, set to 0;
if last.id and year >= 2010 and grpcheck=1; *if still 1 by last.id and it hits at least 2010 then output;
run;
任何时候你想为每个 ID 做一些逻辑(或者,每个按某个变量的值逻辑分组的行集),你首先要设置你的 flag/etc。在 if first.id
语句组中。然后,根据每一行的需要修改您的标志。然后,添加一个 if last.id
组来检查当您点击最后一行时标志是否仍然设置。
在我看来,Proc SQL 可以提供一种非常简单的方法,
proc sql;
select distinct id from have
group by id
having sum(year<=2009 and dummy = 1)=0 and sum(year>=2010 and dummy=0) = 0
;
quit;
我有看起来像这样的面板数据:
ID year dummy
1234 2007 0
1234 2008 0
1234 2009 0
1234 2010 1
1234 2011 1
2345 2008 0
2345 2009 1
2345 2010 1
2345 2011 1
3456 2008 0
3456 2009 0
3456 2010 1
3456 2011 1
随着更多的观察结果遵循相同的模式以及更多与此问题无关的变量。
我想建立一个 ID 处理样本,其中虚拟变量 "switches" 在 2010 年(year<2010 时为 0,year>=2010 时为 1)。在上面的示例数据中,1234 和 3456 会在样本中,而 2345 不会。
我是 SAS 的新手,我想我对 CLASS 和 BY 语句还不够熟悉,无法弄清楚如何做到这一点。
到目前为止我已经这样做了:
data c_temp;
set c_data_full;
if year < 2010 and dummy=0
then trtmt_grp=1;
else pre_grp=0;
if year >=2010 and dummy=1
then trtmt_grp=1;
run;
但这对数据的面板方面没有任何作用。我不知道如何进行最后一步,即每年仅选择 trtmt_grp 为 1 的 ID。
感谢所有帮助!谢谢!
我想你可能想要一个双 DOW 循环。第一个循环在 ID 级别计算您的 TRTMT_GRP 标志,第二个循环计算 select 详细记录。
data want ;
do until (last.id);
set c_data_full;
by id dummy ;
if first.dummy and dummy=1 and year=2010 then trtmt_grp=1;
end;
do until (last.id);
set c_data_full;
by id ;
if trtmt_grp=1 then output;
end;
run;
不要认为您需要双 DoW 循环,除非您需要将数据附加到其他行。如果每个匹配的 ID 只需要一行,简单的单次传递就足够了。
data want;
set have;
by id;
retain grpcheck; *keep its value for multiple passes;
if first.id and year < 2010 then grpcheck=1; *reset for each ID to 1 (kept);
else if first.id and year ge 2010 then grpcheck=0;
if (year<2010) and (dummy=1) then grpcheck=0; *if a non-zero is found before 2010, set to 0;
if (year >= 2010) and (dummy=0) then grpcheck=0; *if a 0 is found at/after 2010, set to 0;
if last.id and year >= 2010 and grpcheck=1; *if still 1 by last.id and it hits at least 2010 then output;
run;
任何时候你想为每个 ID 做一些逻辑(或者,每个按某个变量的值逻辑分组的行集),你首先要设置你的 flag/etc。在 if first.id
语句组中。然后,根据每一行的需要修改您的标志。然后,添加一个 if last.id
组来检查当您点击最后一行时标志是否仍然设置。
在我看来,Proc SQL 可以提供一种非常简单的方法,
proc sql;
select distinct id from have
group by id
having sum(year<=2009 and dummy = 1)=0 and sum(year>=2010 and dummy=0) = 0
;
quit;