2

我有看起来像这样的面板数据:

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 处理样本,其中虚拟变量在 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。

感谢所有帮助!谢谢!

4

3 回答 3

3

不要认为您需要双 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 做一些逻辑(或者,每个逻辑分组的行集由某个变量的值),你首先设置你的标志/等。在一个if first.id语句组中。然后,根据每一行修改您的标志。然后,添加一个if last.id组,该组检查当您击中最后一行时标志是否仍然设置。

于 2015-11-30T17:29:45.213 回答
1

我想你可能想要一个双 DOW 循环。第一个循环在 ID 级别计算您的 TRTMT_GRP 标志,第二个循环选择详细记录。

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;
于 2015-11-30T16:57:08.810 回答
1

在我看来,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;
于 2015-11-30T19:17:46.443 回答