SAS-在满足条件后,按ID删除观测值

SAS-在满足条件后,按ID删除观测值,sas,Sas,对于每个ID,我想删除伪变量取值为1之后的所有观察值。例如: 我掌握的数据如下: ID TIME DUMMY 1 1 0 1 2 0 1 3 1 1 4 0 2 1 0 2 2 0 2 3 1 3 1 1 3 2 0 3 3 0 我想要的输出: ID TIME DUMMY 1 1 0 1 2

对于每个ID,我想删除伪变量取值为1之后的所有观察值。例如:

我掌握的数据如下:

ID  TIME    DUMMY 
1   1       0
1   2       0
1   3       1
1   4       0
2   1       0
2   2       0
2   3       1
3   1       1
3   2       0
3   3       0
我想要的输出:

ID  TIME    DUMMY 
1   1       0
1   2       0
1   3       1
2   1       0
2   2       0
2   3       1
3   1       1

这是一种方法:

data want(drop = a);
  set have;
  by id;
  retain a;
  if first.id then a = 1;
  if a = 1 then output;
  if dummy = 1 then a = 0;
run;

我将使用
输出
保留
返回
语句的帮助来覆盖
数据
步骤循环。
RETURN
语句强制
DATA
步骤立即转到下一个迭代。这将删除DUMMYs=1个观测值之间的所有观测值:

data want;
    set test;
    drop count;
    if DUMMY = 1 then do;
        retain count;
        count = 1;
        output;
        return;
    end;

    if count = 1 and DUMMY ne 1 then do;
        retain count;
        delete;
        return;
    end;
    output;

run;
输出:

                                ID    TIME    DUMMY

                                 1      1       0
                                 1      2       0
                                 1      3       1
                                 2      3       1
                                 3      1       1

使用道指循环似乎比保留和滞后更优雅。 请在此处阅读有关此编程结构的更多信息: 它非常有用

data want(drop=printit);
    if 0 then set have;
    printit = last.id;
    do until(last.id or dummy);
        set have;
        by id;
        if printit then output;
    end;
run;

do
语句前面的一行只是为了保持列的原始顺序。

那么,到目前为止您尝试了什么?问题不是很清楚,你想放弃多少观察。因为在第一个虚拟对象=1之后,您放弃了一个观察。但后来你在数据集的末尾删除了两个观察结果..抱歉误解了;对于给定的ID,我希望在伪变量取值1后删除所有观察值。这就是为什么在我的示例中,丢弃的观察值的数量根据ID而变化。从第三行到最后一行应该是:如果滞后(虚拟)=1,那么a=0;谢谢如果您有两个连续的ID,每一行都有一个dummy=1,那么当您实际想要保留第二个ID时,您的滞后条件将删除第二个ID。我上面所做的修复避免了这样做。看起来还可以,但为了清楚起见,我应该使用更好的变量名(而不是
a
作为触发器)。这并没有回答我最初的问题。您的输出与问题中显示的输出不匹配。用户667489建议了一种正确的方法,以及我建议的修改。谢谢你说你想删除一个伪变量取值1之后的所有观察结果。@YickLeung For ID=2在伪变量取值1之前你已经删除了两个观察结果。
如果printit然后输出输出除每个ID中最后一条记录以外的任何记录(按组)?首先要了解的是,其中有2个循环有效。整个数据步骤的隐式循环和显式do循环。退出do循环有两种可选条件,一种是by group ended(so last.id=1),另一种是dummy=1。退出内部循环后,执行返回到do语句上方的行,并更新printit:如果do循环因dummy退出,则为0;如果因last.id退出,则为1。因此,在dummy=1之后和by group更改之前出现的记录将被忽略。使用
put\u all就在do语句之前,查看发生了什么。如果第一行的dummy=0,并且它不是by组中的唯一一行,它如何获得输出?从我对它的理解来看,显式do循环将直接通过by组中的最后一行,并仅输出该行。然后,在为下一组再次启动循环之前,printit将设置为1。如果您能扩展一下您的答案(根据您自己的建议)来解释它是如何工作的,我将不胜感激,因为这将帮助人们更好地理解它。方便地说,在第一次迭代之前,last.id默认为1,因此printit=1。直到条件仅在执行do块后才计算,因此发生时last.id更新为0。Dummy在第一次迭代中不扮演任何角色。