**************************************************************************************************** * PROGRAM OVERVIEW **************************************************************************************************** * * PROGRAM: codedistribution_output.sas * Created (mm/dd/yyyy): 04/16/2021 * *-------------------------------------------------------------------------------------------------- * PURPOSE: The macro creates both the Full Code Distribution and Total Code Counts output * * Program inputs: * * Program outputs: * * PARAMETERS: * * Programming Notes: * * *-------------------------------------------------------------------------------------------------- * CONTACT INFO: * Sentinel Coordinating Center * info@sentinelsystem.org * ***************************************************************************************************; %macro codedistribution_output; /* This macros produces output for a specific distribution type (EXP or HOI) */ %macro codedistribution_type(distindextype=); /* Compute group label to display in title */ %let grouplabel=; %isdata(dataset=labelfile); %if %eval(&nobs>0) %then %do; proc sql noprint; select label into :grouplabel trimmed from labelfile where lower(group)="&group." and runid = "&runid" and %if &distindextype. eq exp %then %do; lower(labeltype)="grouplabel"; %end; %else %do; lower(labeltype)="outcomelabel"; %end; quit; %end; %if %str("&grouplabel.") eq %str("") %then %let grouplabel = %trim(&group.); /* Compute Total Code Counts (must be processed first to restrict to topncodedist */ proc sort data=codedistdata (where=(lower(group) = "&group." and runid = "&runid" and lower(distindextype) = "&distindextype.")) out=codedistcounts (keep = runid distindexlist code description codetype codecat codetype totalN); by distindexlist descending totalN code; run; data codedistcounts; set codedistcounts; by distindexlist descending totalN code; if first.distindexlist then do; codeCount = TotalN; end; retain codeCount; else do; codeCount = codeCount; end; run; proc sql noprint undo_policy = none; create table codedistcounts as select distinct code ,description ,codecat ,codetype Label="Code Type" ,sum(codeCount) as N from codedistcounts group by code, description, codecat, codetype order by N desc; quit; data codedistcounts; set codedistcounts; if _N_ <= &topncodedist.; run; /* Compute and output Full Code Distribution */ %tableletter(); proc sql; create table repdata.table&tablenum.&tableletter as select dist.group ,dist.distindexlist ,dist.code Label="Code" ,dist.description Label="Code Description" ,dist.codecat Label="Code Category" ,dist.codetype Label="Code Type" ,dist.caresetting Label="Encounter Care Setting" ,dist.totalN as totalN Label="Overall Counts" from codedistdata (where=(lower(group) = "&group." and runid = "&runid" and lower(distindextype) = "&distindextype.")) as dist join codedistcounts as code on dist.codecat=code.codecat and dist.codetype=code.codetype and dist.code=code.code order distindexlist, code; quit; data repdata.table&tablenum.&tableletter; length caresetting codetype codecat code $200 description $700; set repdata.table&tablenum.&tableletter (rename = (code = _code caresetting = _caresetting TotalN = _TotalN description = _description codetype = _codetype codecat = _codecat)); by distindexlist; if first.distindexlist then do; caresetting = ''; TotalN = 0; code = ''; description = ''; codecat = ''; codetype = ''; end; TotalN + _TotalN; caresetting = cat(strip(_caresetting), '^n', caresetting); code = cat(strip(_code), '^n', code); description = cat(strip(_description), '^n', description); codecat = cat(strip(_codecat), '^n', codecat); codetype = cat(strip(_codetype), '^n', codetype); retain caresetting code description codecat codetype; if last.distindexlist then do; caresetting = substr(caresetting,1,length(strip(caresetting)) - 2); description = substr(description,1,length(strip(description)) - 2); codetype = substr(codetype,1,length(strip(codetype)) - 2); codecat = substr(codecat,1,length(strip(codecat)) - 2); code = substr(code,1,length(strip(code)) - 2); row_separator + 1; output; end; run; proc sort data=repdata.table&tablenum.&tableletter(drop = _:); by descending totalN; run; %let title = %quote(Table &tablenum.&tableletter.. Full Code Distribution of &grouplabel. in the &database. from &startdateformatted. to &enddateformatted.); ods escapechar="^"; %if &destination = excel %then %do; ods excel options(sheet_name="Table &tablenum.&tableletter." tab_color="teal"); %end; ods proclabel = "Table &tablenum.&tableletter."; proc report data=repdata.table&tablenum.&tableletter nofs nowd spanrows missing split='*' style(header)=[rules=none vjust=b frame=void background=BGR borderleftcolor = BGR] style(report)=[rules=none frame=void cellpadding =1.75pt]; column distindexlist code description codecat codetype totalN caresetting row_separator; define distindexlist / noprint; define row_separator / analysis noprint; define code / display 'Code' style(column)=[just=L tagattr="type:String" width=20%] style(header)=[just=L background = bgr borderleftcolor = BGR]; define description / display 'Code Description' style(column)=[just=c tagattr="type:String" width=30%] style(header)=[just=c background = bgr borderleftcolor = BGR]; define codecat / display 'Code Category' style(column)=[width=.7in just=c tagattr="type:String"] style(header)=[just=c background = bgr borderleftcolor = BGR]; define codetype / display 'Code Type' style(column)=[width=.7in just=c tagattr="type:String"] style(header)=[just=c background = bgr borderleftcolor = BGR]; define totalN / display 'Overall Counts' format=comma10.0 style(column)=[width=.7in just=c vjust=c] style(header)=[just=c background = bgr borderleftcolor = BGR]; define caresetting / display 'Encounter Care Setting' style(column)=[width=.7in just=c] style(header)=[just=c background = bgr borderleftcolor = BGR]; /* Add title */ compute before _page_ / style=[background=white font_weight=bold just=L foreground=black vjust=b bordertopcolor=white borderbottomwidth=&bordersize tagattr="wrap:yes" nobreakspace=off cellheight=.3in]; line "&title."; endcomp; compute row_separator; call define (_row_,'style','style=[borderbottomcolor=lightgrey borderbottomwidth=.5pt] ' ); endcomp; compute after _page_ / style=[bordertopcolor=black bordertopwidth=&bordersize borderbottomcolor=white borderleftcolor=white borderrightcolor=white]; line ' '; endcomp; run; /* Output Total Code Counts */ %tableletter(); data repdata.table&tablenum.&tableletter; set codedistcounts; run; %let title = %quote(Table &tablenum.&tableletter.. Total Code Counts of &grouplabel. in the &database. from &startdateformatted. to &enddateformatted.); ods escapechar="^"; %if &destination = excel %then %do; ods excel options(sheet_name="Table &tablenum.&tableletter." tab_color="teal"); %end; ods proclabel = "Table &tablenum.&tableletter."; proc report data=repdata.table&tablenum.&tableletter nofs nowd spanrows missing split='*' style(header)=[rules=none vjust=b frame=void background=BGR borderleftcolor = BGR] style(report)=[rules=none frame=void cellpadding =1.75pt]; column code description codecat codetype N ; define code / display 'Code' group order order= data style(column)=[just=L tagattr="type:String" width=20%] style(header)=[just=L background = bgr borderleftcolor = BGR]; define description / display 'Code Description' group order order= data style(column)=[just=c tagattr="type:String" width=30%] style(header)=[just=c background = bgr borderleftcolor = BGR]; define codecat / display 'Code Category' group order order= data style(column)=[width=.7in just=c tagattr="type:String"] style(header)=[just=c background = bgr borderleftcolor = BGR]; define codetype / display 'Code Type' group order order= data style(column)=[width=.7in just=c tagattr="type:String"] style(header)=[just=c background = bgr borderleftcolor = BGR]; define N / display 'Overall Counts' group order order= data format=comma10.0 style(column)=[width=.7in just=c] style(header)=[just=c background = bgr borderleftcolor = BGR]; /* Add title */ compute before _page_ / style=[background=white font_weight=bold just=L foreground=black vjust=b bordertopcolor=white borderbottomwidth=&bordersize tagattr="wrap:yes" nobreakspace=off cellheight=.3in]; line "&title."; endcomp; compute after _page_ / style=[bordertopcolor=black bordertopwidth=&bordersize borderbottomcolor=white borderleftcolor=white borderrightcolor=white]; line ' '; endcomp; run; %mend codedistribution_type; %let tablecount=1; proc sql noprint; select count(*) into :numgroupscodedist trimmed from GroupsDist; quit; %do loopcount = 1 %to &numgroupscodedist.; %let codedistexp = N; %let codedisthoi = N; data _null_; set GroupsDist; if &loopcount. = _N_; call symputx('runid', runid); call symputx('group', group); if missing(topncodedist) then call symputx('topncodedist',25); else call symputx('topncodedist',topncodedist); if index(upcase(codedist), "EXP") > 0 then call symputx('codedistexp', 'Y'); if index(upcase(codedist), "HOI") > 0 then call symputx('codedisthoi', 'Y'); run; %if &codedistexp. eq Y %then %do; * Defensive: make sure the requested data is available; %let obscount=0; proc sql noprint; select count(*) into :obscount from codedistdata where lower(group) = "&group." and runid = "&runid" and lower(distindextype) = "exp"; quit; %if %eval(&obscount. > 0) %then %codedistribution_type(distindextype=exp); %end; %if &codedisthoi. eq Y %then %do; * Defensive: make sure the requested data is available; %let obscount=0; proc sql noprint; select count(*) into :obscount from codedistdata where lower(group) = "&group." and runid = "&runid" and lower(distindextype) = "hoi"; quit; %if %eval(&obscount. > 0) %then %codedistribution_type(distindextype=hoi); %end; %end; *numgroupscodedist; %mend codedistribution_output;