I'm trying to understand the below step which was written by other programmer. I feel that this step can be written in better way. In the below step I want to know how the record count increases in the output dataset. Any help?
253 DATA WORK.BASELINE3; 254 SET BASELINE3; 255 POSTNG_DT = BAS_STRT_DT - 1; 256 DAYS_OF_PO = BAS_FINISH_DT - BAS_STRT_DT +1; 257 DO WHILE (BAS_FINISH_DT > POSTNG_DT); 258 POSTNG_DT = intnx("day",POSTNG_DT,1); 259 OUTPUT; 260 END; 261 RUN; NOTE: There were 7779 observations read from the data set WORK.BASELINE3. NOTE: The data set WORK.BASELINE3 has 21215 observations and 31 variables.
No need to INTNX() when moving by DAY since dates are just number of days.
If you need to move by some other interval that is not a constant amount, such as MONTH or YEAR, then it is less confusing to use an OFFSET integer so that your DO loop does not need WHILE() or UNTIL().
For example if you wanted to output one observation per month in an interval between a STARTDT and ENDDT variables you could do.
data want;
set have;
do offset=0 to intck('month',startdt,enddt);
date = intnx('month',startdt,offset,'b');
format date date9.;
output;
end;
run;
Since dates are counts of days, INTNX with "day" is usually overkill.
You can use an iterative DO loop instead:
do postng_dt = bas_strt_dt to bas_finish_dt;
output;
end;
The first calculation of postng_dt serves no purpose.
Since you run a loop for every observation read from baseline3 that includes an OUTPUT, you get multiple observations in the output dataset.
The usual warning: overwriting a dataset in one step is dangerous and can cause you to lose all work up to this point.
Here's a technique to figure out what is happening and if it can be re-coded (as @Kurt_Bremser suggests)
Create a simple example input dataset, then add PUT statements to the code, so you can see what is happening:
Note: I added a "break" variable because I had a typo and the do loop went infinite on me.
data baseline3 ;
infile cards ;
input
bas_strt_dt : date9.
bas_finish_dt : date9. ;
cards ;
15May2022 20May2022
16May2022 17May2022
;
DATA WORK.BASELINE3;
break=0 ;
SET BASELINE3;
put bas_strt_dt= bas_finish_dt= bas_strt_dt= DATE. bas_finish_dt= DATE. ;
POSTNG_DT = BAS_STRT_DT - 1;
DAYS_OF_PO = BAS_FINISH_DT - BAS_STRT_DT +1;
DO WHILE (BAS_FINISH_DT > POSTNG_DT);
POSTNG_DT = intnx("day",POSTNG_DT,1);
put bas_strt_dt= bas_finish_dt= POSTNG_DT= bas_strt_dt= DATE. bas_finish_dt= DATE. POSTNG_DT=DATE. ;
break+1 ;
if break > 10 then stop ;
OUTPUT;
END;
RUN;
Here is an easier way to implement your "BREAK" concept.
SAS will allow you combine iterative DO and WHILE().
DO BREAK=1 to 10 WHILE (BAS_FINISH_DT > POSTNG_DT);
...
END;
No need to INTNX() when moving by DAY since dates are just number of days.
If you need to move by some other interval that is not a constant amount, such as MONTH or YEAR, then it is less confusing to use an OFFSET integer so that your DO loop does not need WHILE() or UNTIL().
For example if you wanted to output one observation per month in an interval between a STARTDT and ENDDT variables you could do.
data want;
set have;
do offset=0 to intck('month',startdt,enddt);
date = intnx('month',startdt,offset,'b');
format date date9.;
output;
end;
run;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Select SAS Training centers are offering in-person courses. View upcoming courses for: