**************************************************************************************************** * PROGRAM OVERVIEW **************************************************************************************************** * * PROGRAM: ms_agestrat.sas * * Created (mm/dd/yyyy): 12/19/2014 * Last modified: 05/15/2018 * Version: 1.4 * *-------------------------------------------------------------------------------------------------- * PURPOSE: * This program creates an age group variable consisting of custom, user-specified groupings, * with allowance for any mix of time units. * * Program inputs: * -SAS data file (.SAS7BDAT format) including START and END dates to calculate age * for each observation and a text string defining the age stratifications * * or * * -SAS data file (.SAS7BDAT format) including a START date and a constant date * parameter to calculate age for each observation and a text string * defining the stratifications * * Program outputs: * -SAS data file (.SAS7BDAT format) containing the age group for each observation * * PARAMETERS: * -INFILE = Input file containing start date (required) * -OUTFILE = Output file * -STARTDT = Start date to measure age * -ENDDT = End date to measure age * -TIMESTRAT = Age groups for stratification * * Programming Notes: * -The default value for the age stratification text string is * 00-01 02-04 05-09 10-14 15-18 19-21 22-44 45-64 65-74 75+ * * *-------------------------------------------------------------------------------------------------- * CONTACT INFO: * Sentinel Coordinating Center * info@sentinelsystem.org * *-------------------------------------------------------------------------------------------------- * CHANGE LOG: * * Version Date Initials Comment (reference external documentation when available) * ------- -------- -------- --------------------------------------------------------------- * 1.4 05/15/18 AP Added AgeGroupNum to output dataset for correct AgeGroup sort * ***************************************************************************************************; %macro MS_AGESTRAT(INFILE=,OUTFILE=,STARTDT=,ENDDT=,TIMESTRAT=); %put =====> MACRO CALLED: ms_agestrat v1.4; %global NBSTRAT AGETYP MINAGE MAXAGE AGETHRESH; *Converting constant end date to value in numeric if required; %if %index(&ENDDT.,/) %then %do; data _null_; Call Symputx('ENDDT',put(input("&ENDDT",mmddyy10.),best12.)); run; %put END DATE CONVERTED TO NUMERIC: &ENDDT; %end; *Setting default values for time text string (years); %if %str("&TIMESTRAT.")=%str("") %then %do; %let TIMESTRAT=00-01 02-04 05-09 10-14 15-18 19-21 22-44 45-64 65-74 75+; %end; *Counting time categories; %let NUMARG=0; %do %while(%qscan(&TIMESTRAT,&NUMARG+1,%str( )) ne %str()); %let NUMARG = %eval(&NUMARG+1); %end; %let NBSTRAT=&NUMARG.; *Defining each time category; data _NULL_; format AgeThresh $200. AgeTyp $200.; do i=1 to &NBSTRAT.; _agetyp=compress(scan("&TIMESTRAT.",i*2-1),'DWMQY','klu'); _agetyp=TRANWRD(UPCASE(_agetyp),'Y','Years'); _agetyp=TRANWRD(UPCASE(_agetyp),'D','Days'); _agetyp=TRANWRD(UPCASE(_agetyp),'W','Weeks'); _agetyp=TRANWRD(UPCASE(_agetyp),'Q','Quarters'); _agetyp=TRANWRD(UPCASE(_agetyp),'M','Months'); if _agetyp ne '' then AgeTyp=strip(AgeTyp)||" "||strip(_Agetyp); else AgeTyp=strip(AgeTyp)||' Years'; AgeThresh=strip(AgeThresh)||" "||compress(scan("&TIMESTRAT.",i*2-1),'DWMQY','lu'); if i=1 then MinAge=input(AgeThresh,best.); if i=&NBSTRAT. then do; MaxAge=input(compress(scan("&TIMESTRAT.",i*2),'DWMQY','lu'),best.); if MaxAge=. then MaxAge=99999; end; output; end; call symputx('AGETHRESH',AgeThresh); call symputx('AGETYP',AgeTyp); call symputx('MINAGE',MinAge); call symputx('MAXAGE',MaxAge); run; *Echoing macro variable; %put _LOCAL_; *Assigning age categories; data &OUTFILE.(drop=i comparedt); length AgeGroupNum 3 MinAgeDt MaxAgeDt 4; set &INFILE.; format MinAgeDt MaxAgeDt date9. AgeGroup $9.; MinAgeDt = intnx(scan("&AGETYP.",1),&STARTDT.,&MINAGE.,'sameday'); if &MAXAGE.=99999 then MaxAgeDt=intnx('Years',&STARTDT.,110,'sameday'); else if mod(year(&STARTDT.),4)= 0 and month(&STARTDT.) = 2 and day(&STARTDT.) = 29 then MaxAgeDt= intnx(scan("&AGETYP.",&NBSTRAT.),&STARTDT.,&MAXAGE.+1,'sameday'); else MaxAgeDt= intnx(scan("&AGETYP.",&NBSTRAT.),&STARTDT.,&MAXAGE.+1,'sameday')-1; AgeGroup=""; if MinAgeDt <= &ENDDT. <= MaxAgeDt then do; do i=&NBSTRAT. to 1 by -1; if mod(year(&STARTDT.),4)= 0 and month(&STARTDT.) = 2 and day(&STARTDT.) = 29 then comparedt = intnx(scan("&AGETYP.",i),&STARTDT.,input(scan("&AGETHRESH.",i),best.),'sameday')+1; else comparedt = intnx(scan("&AGETYP.",i),&STARTDT.,input(scan("&AGETHRESH.",i),best.),'sameday'); if &ENDDT. >= comparedt then do; AgeGroup = scan("&TIMESTRAT.",i,' '); AgeGroupNum=i; leave; end; end; end; run; %put NOTE: ******** END OF MACRO: ms_agestrat v1.4 ********; %mend MS_AGESTRAT;