SAS / SQL分组并保留所有行

时间:2019-12-19 11:59:47

标签: plsql group-by sas proc-sql

我有一个像这样的表,可以及时观察某些帐户的行为,这里是两个帐户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,如果date等于mob=0,如果没有date组则等于acc_id mob=0的{​​{1}}。

因此,预期输出为:

acc_id

第二个帐户没有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中实现?

2 个答案:

答案 0 :(得分:1)

这是数据步骤方法

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;

答案 1 :(得分:1)

似乎很简单。只需用两种方式计算最短日期,然后使用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