【问题标题】:SAS - Compare observation to previous observations?SAS - 将观察结果与以前的观察结果进行比较?
【发布时间】:2014-05-29 18:20:31
【问题描述】:

我有以下数据:

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

【问题讨论】:

  • 您的意思是返回所有帐户的所有行,其中帐户有一个非重复的日期条目?
  • 是的,我认为这可能是更好的表达方式。

标签: sas datastep


【解决方案1】:

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

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

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;

【讨论】:

  • 很好的答案!我有一个类似于@Joe 的答案,但我只知道使用 Proc SQL 会有更顺畅的方式(尽管我无法确定)。
【解决方案2】:

这样的事情会奏效。如果尚未按帐户/日期对数据进行排序,则检查每个 last.date 行。如果第一行last.date 也不是last.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;

【讨论】:

  • 好答案,但我认为 _n_ = 1 by 1 在这里是多余的,因为您实际上并没有在 DoW 循环中使用 _n_。你可以写do until(last.acct);,这样就可以了。
  • 它可能是,但它有点传统,所以我离开它:)
猜你喜欢
  • 2014-11-27
  • 1970-01-01
  • 2013-07-12
  • 2018-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多