2016-06-22 5 views
0

Ich versuche, dieses Programm zu beenden, das eine Tabelle der Datumsbereiche entsprechend der Datenspalte namens shop_dttm ausgeben soll. Es gibt noch andere Faktoren, die erfüllt sein müssen, bevor eine Beobachtung in einen Datumsbereich aufgenommen werden kann. Alle anderen Spalten des Datensatzes müssen für zwei Beobachtungen gleich sein, damit diese Beobachtungen im selben Datumsbereich berücksichtigt werden. Momentan gibt das Programm mir alle Datumsbereiche, die in meinem Datensatz vorhanden sind; es gibt jedoch jeden Datumsbereich als einen Tag-Bereich aus. Zum Beispiel, anstatt mir den Bereich 7/1/15 bis 7/3/15 zu geben, gibt es mir eine Beobachtung vom 01.07.15 bis 02.07.15 und eine weitere Beobachtung vom 02.07.15 bis 07/3/15. Ich suche nach einer Möglichkeit, dieses Programm zu kombinieren, diese aufeinanderfolgenden Bereiche zu kombinieren, um Bereiche zu erhalten, die länger als einen Tag sind.SAS Datumsbereich Algorithmus Iteration Debug

Code:

%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; 

Daten haben:

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 

Daten wollen:

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 

Antwort

0

Unter der Annahme, & Lage & Klasse & Länge ist eine eindeutige ID in Ihrem OUTDATA-Datensatz können wir berechne einfach min/max/ra nge des Datums und gibt die letzte Zeile aus.

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;