SAS - 将观察结果与之前的观察结果进

时间:2014-05-29 18:20:31

标签: sas datastep

我有以下数据:

acct        date
11111       01/01/2014
11111       01/01/2014
11111       02/02/2014
22222       01/01/2014
22222       01/01/2014
33333       01/01/2013
33333       03/03/2014
44444       01/01/2014
44444       01/01/2014
44444       01/01/2014

在SAS中完成以下操作的最佳方法是什么?我想比较每个帐号的日期,并返回至少有一个日期不匹配的帐户的所有记录。

因此,对于上面的数据集,我想最终得到以下内容:

acct        date
11111       01/01/2014
11111       01/01/2014
11111       02/02/2014
33333       01/01/2013
33333       03/03/2014

2 个答案:

答案 0 :(得分:2)

单个PROC SQL可以解决这个问题。使用count(不同日期)来计算不同日期的数量。按acct进行分组按acct进行计数,当结果大于1时,使用having子句对其进行过滤。接下来选择acct和date作为输出列。

这是SAS特定的SQL处理。大多数其他实现都不允许这种构造,你不会在group by子句中放入select中的所有非聚合列。

proc sql noprint;
    create table _output as
    select acct, date format=ddmmyys10.
    from _input
    group by acct
    having count(distinct date) > 1
    order by acct, date;
   quit;

答案 1 :(得分:1)

这样的事情会起作用。按行/日期对数据进行排序(如果尚未排序),然后检查每个last.date行。如果第一个last.date行也不是last.acct,那么它是需要输出响应者的一组行。这里我每个日期/ acct组合只输出一行:

data want;
set have;
by acct date;
if (last.date) and not (last.acct) then do;
  flg=1;
  output;
end;
else if last.date and flg=1 then output;
else if first.acct then flg=0;
run;

如果你需要所有的行,那么你需要采取上述步骤并将其合并回原始行,或者你可以做一个DoW循环:

data want;
do _n_=1 by 1 until (last.acct);
 set have;
 by acct date;
 if (last.date) and not (last.acct) then do;
  flg=1;
 end;
end;
do _t_ = 1 by 1 until (last.acct);
 set have;
 by acct date;
 if flg=1 then output;
end;
run;