SAS日期范围算法迭代调试

时间:2016-06-22 13:33:41

标签: date debugging sas

我正在尝试完成此程序,该程序旨在根据名为shop_dttm的数据列输出日期范围表。在将一个观察结果包括在日期范围内之前,还有其他因素需要满足。对于在同一日期范围内考虑的那些观测值,数据集的所有其他列必须相等才能进行两次观察。目前,该程序为我提供了数据集中存在的所有日期范围;但是,它将每个日期范围输出为一天范围。例如,不是给我7/1/15到7/3/15的范围,而是给我一个7/1/15到7/2/15的观测和另一个7/2/15到7 /的观测。 3/15。我正在寻找一种方法来让这个程序结合这些连续范围来获得超过一天的范围。

代码:

%let indata = WORK.OFFSELL_ZE;
%let location = city_cd;
%let class = shop_car_type_cd;
%let length = lor;
%let shop_dttm = datepart(shop_dttm);
%let chkdate = shop_dttm;
%let arv_dt = arv_dt;
%let numconday = 0;
%let outdata = WORK.shop_date_range_ZE;

proc sort data = &indata nodupkey;
    by &location &class &length &chkdate;
run;

data one;
    set &indata;
    by &location &class &length &chkdate;
    tempdate = lag(&chkdate);
    if (first.&location & first.&class & first.&length) then tempdate=.;
    retain cflag;
    if (first.&location & first.&class & first.&length) then cflag = 1 and consecutive = 0;
    if &chkdate ne tempdate+1 or &location ne lag(&location) or &length ne lag(&length) or &arv_dt ne lag(arv_dt) 
    or &class ne lag(&class) then cflag = cflag +1;
run;

data two(keep = &location &class &length cflag consecutive);
    set one; 
    by &location &class &length cflag;
    retain consecutive;
    if first.cflag then consecutive = 0;
    if last.cflag and consecutive>=&numconday;
    consecutive = consecutive +1;

run;

data three;
    merge one two(in=a);
    by &location &class &length cflag;
    if a;
run;

proc sort data=three;
    by &location &class &length cflag &chkdate;
run;

data four;
    set three;
    by &location &class &length cflag &chkdate;
    retain firstdate;
    if first.cflag then firstdate = &chkdate;
    firstdate = datepart(firstdate);
    lastdate = datepart(lastdate);
    format lastdate firstdate mmddyy10.;
    lastdate = firstdate + consecutive;
    if last.cflag;

run;

proc sort data=four(drop=cflag &chkdate tempdate) out=&outdata;
    by &location &class &length firstdate;
run;

proc sql;
alter table &outdata
    drop Brand_ZE
    add cflag num label = 'cflag' format = BEST.
    add advance_days num label = 'advance_days' format = BEST.
    add range_length num label = 'range_length' format = BEST.
    modify arv_dt date format = mmddyy10.;
update &outdata
    SET advance_days = arv_dt - firstdate;
update &outdata
    SET range_length = consecutive;
update &outdata
    SET cflag = cflag;
alter table &outdata
    drop consecutive;

quit;

数据有:

 city_cd      shop_car_type_cd         lor          arv_dt        shop_dttm
    atl            bcar                     1          6/1/16          6/1/16
    atl            bcar                     1          6/1/16          6/3/16
    atl            bcar                     1          6/1/16          6/2/16
    atl            ccar                     1          6/1/16          6/4/16
    atl            bcar                     1          6/1/16          6/5/16
    atl            bcar                     1          6/1/16          6/6/16
    atl            bcar                     2          6/2/16          6/7/16

数据想要:

 city_cd   shop_car_type_cd   lor    arv_dt    shop_start  shop_end  consec_days
    atl           bcar          1    6/1/16     6/1/16       6/3/16     3
    atl           bcar          1    6/1/16     6/5/16       6/6/16     2
    atl           bcar          2    6/2/15     6/7/16       6/7/16     0
    atl           ccar          1    6/1616     6/4/2016     6/4/16     0

1 个答案:

答案 0 :(得分:0)

假设& location& class& length是OUTDATA数据集中的唯一ID,我们可以计算日期的最小/最大/范围并输出最后一行。

proc sort data = &indata ;
    by &location &class &length DESCENDING &chkdate ;
run;

data &outdata;
    do until (last.&length);
        set &indata;
        by &location &class &length;
        shop_start = min(shop_start,&chkdate); 
        shop_end   = max(shop_end,&chkdate);
    end;
    consec_days    = shop_end - shop_start + 1;
    format &chkdate shop_start shop_end mmddyy10.;
run;