SAS/SQL 分组并保留所有行

SAS/SQL group by and keeping all rows

我有一个这样的table,及时观察一些账户的行为,这里有两个账户acc_ids 1和22:

acc_id   date    mob
  1      Dec 13   -1
  1      Jan 14    0
  1      Feb 14    1
  1      Mar 14    2
  22     Mar 14    10
  22     Apr 14    11
  22     May 14    12

我想创建一个列 orig_date 如果 mob=0 等于 date 并且如果 acc_id 组最小 date acc_id 没有 mob=0

因此预期的输出是:

acc_id   date    mob   orig_date
  1      Dec 13   -1     Jan 14
  1      Jan 14    0     Jan 14
  1      Feb 14    1     Jan 14
  1      Mar 14    2     Jan 14
  22     Mar 14    10    Mar 14
  22     Apr 14    11    Mar 14
  22     May 14    12    Mar 14

第二个账号没有mob=0观察,所以orig_date按组设置为min(date)

有没有什么方法可以在 SAS 中实现这一点,最好是一步 proc sql

这是一个数据步骤方法

data have;
input acc_id date $ mob;
datalines;
1  Dec13 -1
1  Jan14  0
1  Feb14  1
1  Mar14  2
22 Mar14  10
22 Apr14  11
22 May14  12
;

data want;
    do until (last.acc_id);
        set have;
        by acc_id;
        if first.acc_id then orig_date=date;
        if mob=0 then orig_date=date;
    end;
    do until (last.acc_id);
        set have;
        by acc_id;
        output;
    end;
run;

看起来很简单。只需以两种方式计算最短日期,然后使用 coalesce() 来选择您想要的那个。

首先让我们将您的打印输出转换为实际数据集。

data have ;
  input acc_id date :anydtdte. mob ;
  format date date9.;
cards;
1      Dec13   -1
1      Jan14    0
1      Feb14    1
1      Mar14    2
22     Mar14    10
22     Apr14    11
22     May14    12
;

要在 MOB=0 时查找 DATE,请使用 CAsE 子句。 PROC SQL 将自动将在 ACC_ID 级别计算的 MIN() 聚合结果重新合并到所有详细信息行。

proc sql ;
create table want as
select *
     , coalesce( min(case when mob=0 then date else . end)
               , min(date)
               ) as orig_date format=date9.
from have
group by acc_id
order by acc_id, date 
;
quit;

结果:

Obs    acc_id         date    mob    orig_date

 1        1      01DEC2013     -1    01JAN2014
 2        1      01JAN2014      0    01JAN2014
 3        1      01FEB2014      1    01JAN2014
 4        1      01MAR2014      2    01JAN2014
 5       22      01MAR2014     10    01MAR2014
 6       22      01APR2014     11    01MAR2014
 7       22      01MAY2014     12    01MAR2014