****************************************************************************************************
*                                           PROGRAM OVERVIEW
****************************************************************************************************
*
* PROGRAM: t5tables_output.sas  
* Created (mm/dd/yyyy): 08/25/2021
*
*--------------------------------------------------------------------------------------------------
* PURPOSE: This macro includes two proc report procedures in order to produce a categorical and 
*          continuous table in the report for Type 5 analyses
*                                        
*  Program inputs:                                                                                   
*   - Dataset(s) computed in %t5tables_createdata
* 
*  Program outputs: 
*   - Dataset(s) to output/repdata for each figure
* 
*  PARAMETERS:  
*   - dataset: input dataset
*   - reporttype: indicator whether to produce categorical (cat) or continuous (dist) metrics
*   
*  Programming Notes:         
*  
*
*--------------------------------------------------------------------------------------------------
* CONTACT INFO: 
*  Sentinel Coordinating Center
*  info@sentinelsystem.org
*
***************************************************************************************************;

%macro t5tables_output(dataset=, reporttype=);

	%put =====> MACRO CALLED: t5tables_output;
	
	proc sql noprint;
	   select max(sortorder1), max(sortorder2)
	   into :maxorder1, :maxorder2
	   from &dataset.;
	quit;
	%put maxorder1 = &maxorder1.;
	%put maxorder2 = &maxorder2.;
	
    %let num_fn = 0;	
	
	%let tabletitle = ;
	%let categories = ;
	%let num_categories = 0;
    %let num_fn=0;

	data _null_;
		set tablefile;
		if "&dataset" = catx('_',table,put(stratificationorder,best.)) then do;
			call symputx('tablesub', tablesub);
            %if %sysfunc(prxmatch(m/T18_|T19_|T20_|T21_|T22_/i,&dataset.)) = 0 %then %do;
			call symputx('categories', categories);
            %end;
			if tablesub = 'overall' and "&stratifybydp." = "Y" then call symputx('tabletitle', ', by Data Partner');
			else call symputx('tabletitle', tabletitle);
		end;
	run;

    /*Footnotes:
        - footnote table for dose generated in tables footnotes generated in t5tables_createdata */
   data _footnotes;
       length footnote_order 3; 
       set %if %sysfunc(prxmatch(m/T18_|T19_|T20_|T21_|T22_/i,&dataset.)) > 0 %then %do;
                %substr(&dataset.,1,3)_lookup_footnotes_dose(where=(order not in (0
                %if &collapse_vars. ne race | %index(&tablesub., race)=0 %then %do;
                2
                %end; 
                )))
           %end;
           %else %do;
                lookup.lookup_footnotes(where=(type = "t5tablefig" and order in (0 
                %if &collapse_vars. = race & %index(&tablesub., race)>0 %then %do;
                2    
                %end;
                )))
           %end;
           ;
           by order;
           footnote_order = _n_;
    run;
     
    proc sql noprint;
        select count(order) into: num_fn trimmed
        from _footnotes;
      
        %if &num_fn > 0 %then %do;
          select description into: fn1 - :fn&num_fn.
          from _footnotes
          order by order;
        %end;
    quit;

    %assign_superscripts(type=raceunknown, order = 2);

    /*Assign dose group labels and number of categories*/ 
	%if %sysfunc(prxmatch(m/T18_|T19_|T20_|T21_|T22_/i,&dataset.)) > 0 %then %do;
		data _null_;
			set MASTER_TYPEFILE;
            if _n_ = 1 then do;
			%if %sysfunc(prxmatch(m/T18_/i,&dataset.)) > 0 %then %do;
				call symputx('categories', cfdd_output_cat);	
			%end;
			%if %sysfunc(prxmatch(m/T19_|T20_/i,&dataset.)) > 0 %then %do;
				call symputx('categories', afdd_output_cat);	
			%end;
			%if %sysfunc(prxmatch(m/T21_|T22_/i,&dataset.)) > 0 %then %do;
				call symputx('categories', cumdose_output_cat);	
			%end;
            end;
		run;

        %let num_categories = %sysfunc(countw(&categories, ' '));

		%do c =1 %to &num_categories.;
			%let lbl&c. = Dose Group &c.;
		%end;
		%if &labelfileexists = Y %then %do;
			%let labeltype = ;
			%if %sysfunc(prxmatch(m/T18_/i,&dataset.)) > 0 %then %let labeltype = cfddcatlabel;
			%if %sysfunc(prxmatch(m/T19_|T20_/i,&dataset.)) > 0 %then %let labeltype = afddcatlabel;
			%if %sysfunc(prxmatch(m/T21_|T22_/i,&dataset.)) > 0 %then %let labeltype = cumdosecatlabel;
			data _null_;
				set labelfile(where=(labeltype="&labeltype."));
				%do c = 1 %to &num_categories.;
					if labelvar = "dosecat&c" then call symputx("lbl&c.", label);
				%end;
			run;
		%end;
    %end;

	%let num_categories = %sysfunc(countw(&categories, ' '));

    /*save to REPORTDATA folder and append superscript if necessary*/
	%isdata(dataset=repdata.table&tablenum.&tableletter.);
    %if %eval(&nobs.<1) %then %do;
	data repdata.table&tablenum.&tableletter.;
		set &dataset.;
        %if &collapse_vars. = race & %index(&tablesub., race)>0 %then %do;
            if grouplabel = 'Unknown' then grouplabel= cats(grouplabel, "&super_raceunknown.");
        %end
	run;
    %end;

    /*Assign table labels and titles*/
    %let t5title=;
    %let t5head=;
    %let unit=;
    %let t5distributiontitle=;

    /*unit of analysis*/
    %if %sysfunc(prxmatch(m/T1_|T2_|T18_/i,&dataset.)) > 0 %then %do;
        %let unit = Dispensings;
    %end;
    %if %sysfunc(prxmatch(m/T5_|T6_|T9_|T10_|T19_/i,&dataset.)) > 0 %then %do;
        %let unit = Episodes;
    %end;
    %if %sysfunc(prxmatch(m/T3_|T4_|T7_|T8_|T12_|T20_|T21_|T22_/i,&dataset.)) > 0 %then %do;
        %let unit = Patients;
    %end;
    %if %sysfunc(prxmatch(m/T11_|T13_/i,&dataset.)) > 0 %then %do;
        %let unit = Gaps;
    %end;

    %if %sysfunc(prxmatch(m/T1_/i,&dataset.)) > 0 %then %do;
        %let t5title = Categorical Summary of Days Supplied per Dispensing;
        %let t5head = Number of Dispensings by Days Supplied;
    %end;
    %else %if %sysfunc(prxmatch(m/T2_/i,&dataset.)) > 0 %then %do;
        %let t5title = Continuous Summary of Days Supplied per Dispensing;
        %let t5distributiontitle = Distribution of Days Supplied by Dispensing;
    %end;
    %else %if %sysfunc(prxmatch(m/T3_/i,&dataset.)) > 0 %then %do;
        %let t5title = Categorical Summary of Patients%str(%') Cumulative Treatment Episode Durations;
        %let t5head = Number of Patients by Cumulative Treatment Episode Duration;
    %end;
    %else %if %sysfunc(prxmatch(m/T4_/i,&dataset.)) > 0 %then %do;
        %let t5title = Continuous Summary of Patients%str(%') Cumulative Treatment Episode Durations; 
        %let t5distributiontitle = Distribution of Cumulative Treatment Episode Duration, days;
    %end;
    %else %if %sysfunc(prxmatch(m/T5_/i,&dataset.)) > 0 %then %do;
        %let t5title = Categorical Summary of All Treatment Episodes;
        %let t5head = Number of Treatment Episodes by Duration; 
    %end;
    %else %if %sysfunc(prxmatch(m/T6_/i,&dataset.)) > 0 %then %do;
        %let t5title = Continuous Summary of All Treatment Episodes; 
        %let t5distributiontitle = Distribution of Treatment Episode Durations, days;
    %end;
    %else %if %sysfunc(prxmatch(m/T7_/i,&dataset.)) > 0 %then %do;
        %let t5title = Categorical Summary of First Treatment Episodes;
        %let t5head = Number of Patients by First Treatment Episode Duration; 
    %end;
    %else %if %sysfunc(prxmatch(m/T8_/i,&dataset.)) > 0 %then %do;
        %let t5title = Continuous Summary of First Treatment Episodes;
        %let t5distributiontitle = Distribution of First Treatment Episode Duration, days;
    %end;
    %else %if %sysfunc(prxmatch(m/T9_/i,&dataset.)) > 0 %then %do;
        %let t5title = Categorical Summary of Second and Subsequent Treatment Episodes;
        %let t5head = Number of Treatment Episodes by Duration (Excluding First Treatment Episode);
    %end;
    %else %if %sysfunc(prxmatch(m/T10_/i,&dataset.)) > 0 %then %do;
        %let t5title = Continuous Summary of Second and Subsequent Treatment Episodes; 
        %let t5distributiontitle = Distribution of Treatment Episode Durations Excluding First Treatment Episode, days;
    %end;
    %else %if %sysfunc(prxmatch(m/T11_/i,&dataset.)) > 0 %then %do;
        %let t5title = Continuous Summary of All Treatment Episode Gaps;
        %let t5distributiontitle = Distribution of Treatment Episode Gap Durations, days;
    %end;
    %else %if %sysfunc(prxmatch(m/T12_/i,&dataset.)) > 0 %then %do;
         %let t5title = Continuous Summary of First Treatment Episode Gaps;
         %let t5distributiontitle = Distribution of First Treatment Episode Gap Duration, days;
    %end;
    %else %if %sysfunc(prxmatch(m/T13_/i,&dataset.)) > 0 %then %do;
        %let t5title = Continuous Summary of Second and Subsequent Treatment Episode Gaps;
        %let t5distributiontitle = Distribution of Treatment Episode Durations Excluding First Treatment Episode Gap, days;
    %end;
	%else %if %index(&dataset,T18_) %then %do; 
		%let t5title = Summary of Filled Daily Dose in Each Dispensing; 
		%let t5head = Number of Dispensings by Filled Daily Dose; 
		%let t5distributiontitle=%str(Distribution of Filled Daily Dose);
	%end;
	%else %if %index(&dataset,T19_) %then %do; 
		%let t5title = Summary of Average Filled Daily Dose in Each Treatment Episode; 
		%let t5head = Number of Episodes by Average Filled Daily Dose; 
		%let t5distributiontitle=%str(Distribution of Average Filled Daily Dose);
	%end;
	%else %if %index(&dataset,T20_) %then %do; 
		%let t5title = Summary of Average Filled Daily Dose in Each Patient%str(%')s First Valid Episode; 
		%let t5head = Number of Patients by Average Filled Daily Dose in First Treatment Episode; 
		%let t5distributiontitle=%str(Distribution of Average Filled Daily Dose);
	%end;
	%else %if %index(&dataset,T21_) %then %do; 
		%let t5title = Summary of Cumulative Filled Dose in All Treatment Episodes; 
		%let t5head = Number of Patients by Cumulative Filled Dose; 
		%let t5distributiontitle=%str(Distribution of Cumulative Filled Dose);
	%end;
	%else %if %index(&dataset,T22_) %then %do; 
		%let t5title = Summary of Cumulative Filled Dose in Each Patient%str(%')s First Treatment Episode; 
		%let t5head = Number of Patients by Cumulative Filled Dose in First Treatment Episode; 
		%let t5distributiontitle=%str(Distribution of Cumulative Filled Dose);
	%end;

	/* Categorical */
	%if &reporttype. = cat %then %do;
		
		* Check if continuous metrics are required for dose tables;
		%let output_t5dose_continuous_data=N;
		%if %sysfunc(prxmatch(m/T18_|T19_|T20_|T21_|T22_/i,&dataset.)) > 0 %then %do;
			proc contents data=repdata.table&tablenum.&tableletter. out=_contents noprint;
			quit;

			%let varcount=0;
			proc sql noprint;
			select count(*) into :varcount trimmed from _contents where lowcase(name)="mean_char";
			quit;

			%if %eval(&varcount. > 0) %then %let output_t5dose_continuous_data=Y;
		%end;
        
		%if &destination = excel %then %do;
			ods excel options(sheet_name="Table &tablenum.&tableletter." tab_color="green" flow="1:400"); /*flow=to prevent line break, 400 arbitrarily chosen to ensure long tables are covered*/
		%end;
		ods proclabel = "Table &tablenum.&tableletter.";		
        proc report data=repdata.table&tablenum.&tableletter. nofs nowd spanrows missing
            style(header)=[rules=none frame=void vjust=b borderbottomcolor=bgr bordertopcolor=bgr background=bgr borderleftcolor=black borderrightcolor=black] split='*'
            style(report)=[rules=none frame=void cellpadding=1.75pt];	
			
			column %if &includeheaderrow. = Y %then %do; header %end; order sortorder1 sortorder2 grouplabel total_count_char ("&t5head." 
					  %do s = 1 %to %eval(&num_categories);
		                  %if %sysfunc(prxmatch(m/T18_|T19_|T20_|T21_|T22_/i,&dataset.)) > 0 %then %do;
						  ("^S={ borderleftcolor=bgr bordertopcolor=black}&&lbl&s.."
		                  %end;
		                  %else %do;
						      %let t5cat = %scan(&categories., &s, %str( ));
						      ("^S={ borderleftcolor=bgr bordertopcolor=black}&t5cat. Days"
		                  %end;
						 _&s._char _&s._percent_char)
                      %end;
					)
					%if &output_t5dose_continuous_data. eq Y and &tablesub. eq overall %then %do;
					("^S={}" 
						("^S={ borderleftcolor=bgr borderbottomcolor=black}&t5distributiontitle." minimum_char maximum_char mean_char stddev_char 							 
						)
					)
					%end; 
					;

				%if &includeheaderrow. = Y %then %do;
				define header / group noprint order=data;
				%end;
			   	define order / order noprint order=data;
			   	define sortorder1 / order noprint order=data;
			   	define sortorder2 / order noprint order=data;
				define grouplabel / display ''
					style(column)=[just=L] 
					style(header)=[background = bgr borderleftcolor= bgr borderrightcolor=bgr borderbottomcolor=black];
				define total_count_char / display "Total Number*of &unit."  
					style(column)=[background=$backgroundfmt. tagattr="type:string"] 
					style(header)=[background = bgr borderleftcolor=bgr borderrightcolor=black borderrightwidth=1 borderbottomcolor=black];	
				%do s=1 %to %eval(&num_categories);
					define _&s._char / display "Number of*&unit."  
					style(column)=[background=$backgroundfmt. tagattr="type:string"] 
					style(header)=[background = bgr borderleftcolor=black borderleftwidth=1 borderrightcolor=bgr bordertopcolor=black borderbottomcolor=black];
					define _&s._percent_char / display "Percent of Total*&unit."  
					style(column)=[background=$backgroundfmt. tagattr="type:string"] 
					style(header)=[background = bgr borderleftcolor=bgr borderrightcolor=black borderrightwidth=1 bordertopcolor=black borderbottomcolor=black];	
				%end;
				%if &output_t5dose_continuous_data. eq Y and &tablesub. eq overall %then %do;
					define minimum_char / display "Minimum"  
						style(column)=[tagattr="type:string"] 
						style(header)=[background = bgr borderleftcolor=bgr borderrightcolor=black borderrightwidth=1] format=$nafmt.;	
					define maximum_char / display "Maximum"  
						style(column)=[tagattr="type:string"] 
						style(header)=[background = bgr borderleftcolor=bgr borderrightcolor=black borderrightwidth=1] format=$nafmt.;
					define mean_char / display "Mean"  
						style(column)=[tagattr="type:string"] 
						style(header)=[background = bgr borderleftcolor=bgr borderrightcolor=black borderrightwidth=1] format=$nafmt.;
					define stddev_char / display "Standard*Deviation"  
						style(column)=[tagattr="type:string"] 
						style(header)=[background = bgr borderleftcolor=bgr borderrightcolor=black borderrightwidth=1] format=$nafmt.;
				%end;

            /*format grouplabel*/
            compute grouplabel;
                if sortorder1=0 then do;
					%if &includeheaderrow. = Y %then %do;
						call define (%if &maxorder1.=0 %then %do; _col_ %end; %else %do; _row_ %end;,"style","style=[fontstyle=italic]");
					%end;
					%else %do;
						if &maxorder1=0 then call define (_col_,"style","style=[fontstyle=italic]");
						else call define (_row_,"style","style=[background=libgr font_weight=bold bordertopcolor=black borderbottomcolor=black]");
					%end;
				end;
				else if &maxorder1=1 then call define(_col_,'style','style={indent=.15in}');
				else do;
					if sortorder2 = 0 then call define(_col_,'style','style={indent=.15in}');
					else if sortorder2 ne 0 then call define(_col_,'style','style={indent=.25in}');
				end;
            endcomp;

            /*Add title*/
            compute before _page_ / style=[background=white font_weight=bold just=L foreground=black vjust=b bordertopcolor=black borderbottomcolor=black
                                           borderbottomwidth=&bordersize tagattr="wrap:no" cellheight=.3in];
				line "Table &tablenum.&tableletter.. &t5title. for &reporttitle. in the &database. from &startdateformatted. to &enddateformatted.&tabletitle.";
            endcomp;
          
            /*Add header rows*/
			%if &includeheaderrow. = Y %then %do;
            compute before header / style=[background=libgr foreground=black just=L font_weight=bold bordertopcolor=black bordertopwidth=1 borderbottomcolor=black]; 
				text = header;
				num = 100;
				line text $Varying. num;
            endcomp; 
			%end;

            /* Add Footnotes */
            %if %eval(&num_fn > 0) %then %do;
                compute after / style=[just=L borderbottomcolor=white bordertopcolor=black vjust=T fontsize=&footfontsize. bordertopwidth = &bordersize
                                       nobreakspace=off];
    		    %do f = 1 %to &num_fn.;
                line "^{super &f.}&&fn&f.";
    		    %end;
                endcomp;
            %end;
            %else %do;
                /*Add thick line to bottom of report*/
                compute after _page_ / style=[bordertopcolor=black bordertopwidth=&bordersize borderbottomcolor=white borderleftcolor=white borderrightcolor=white];
                line ' ';
                endcomp;
            %end;
        run;
	%end;	/* Categorical */

	/* Continuous */
	%if &reporttype. = dist %then %do;
	
		%if &destination = excel %then %do;
			ods excel options(sheet_name="Table &tablenum.&tableletter." tab_color="green");
		%end;
		ods proclabel = "Table &tablenum.&tableletter.";		
        proc report data=repdata.table&tablenum.&tableletter. nofs nowd spanrows missing
            style(header)=[rules=none frame=void vjust=b borderbottomcolor=bgr bordertopcolor=bgr background=bgr borderleftcolor=black borderrightcolor=black] split='*'
            style(report)=[rules=none frame=void cellpadding=1.75pt];

			column %if &includeheaderrow. = Y %then %do; header %end; order sortorder1 sortorder2 grouplabel total_count_char ("&t5distributiontitle." min_char p25_char median_char p75_char max_char mean_char std_char);
				%if &includeheaderrow. = Y %then %do;
				define header / group noprint order=data;
				%end;
			   	define order / order noprint order=data;
			   	define sortorder1 / order noprint order=data;
			   	define sortorder2 / order noprint order=data;
				define grouplabel / display ''
					style(column)=[just=L] 
					style(header)=[background = bgr borderleftcolor= bgr borderrightcolor=bgr borderbottomcolor=black];
				define total_count_char / display "Total Number*of &unit." 
					style(column)=[background=$backgroundfmt. tagattr="type:string"] 
					style(header)=[background = bgr borderleftcolor=bgr borderleftwidth=1 borderrightcolor=bgr borderbottomcolor=black];
				define min_char / display 'Minimum' 
					style(column)=[tagattr="type:string"] 
					style(header)=[background = bgr borderleftcolor=black borderleftwidth=1 borderrightcolor=bgr bordertopcolor=black borderbottomcolor=black];	
				define p25_char / display 'Q1' 
					style(column)=[tagattr="type:string"] 
					style(header)=[background = bgr borderleftcolor=black borderrightcolor=bgr borderrightwidth=1 bordertopcolor=black borderbottomcolor=black];	
				define median_char / display 'Median' 
					style(column)=[tagattr="type:string"] 
					style(header)=[background = bgr borderleftcolor=black borderrightcolor=bgr borderrightwidth=1 bordertopcolor=black borderbottomcolor=black];		
				define p75_char / display 'Q3' 
					style(column)=[tagattr="type:string"] 
					style(header)=[background = bgr borderleftcolor=black borderrightcolor=bgr borderrightwidth=1 bordertopcolor=black borderbottomcolor=black];			
				define max_char / display 'Maximum' 
					style(column)=[tagattr="type:string"] 
					style(header)=[background = bgr borderleftcolor=black borderrightcolor=bgr borderrightwidth=1 bordertopcolor=black borderbottomcolor=black];		
				define mean_char / display 'Mean' 
					style(column)=[tagattr="type:string"] 
					style(header)=[background = bgr borderleftcolor=black borderrightcolor=bgr borderrightwidth=1 bordertopcolor=black borderbottomcolor=black];			
				define std_char / display 'Standard*Deviation' 
					style(column)=[tagattr="type:string"] 
					style(header)=[background = bgr borderleftcolor=black borderrightcolor=bgr borderrightwidth=1 bordertopcolor=black borderbottomcolor=black];	

            /*format grouplabel*/
            compute grouplabel;
                if sortorder1=0 then do;
					%if &includeheaderrow. = Y %then %do;
						call define (%if &maxorder1.=0 %then %do; _col_ %end; %else %do; _row_ %end;,"style","style=[fontstyle=italic]");
					%end;
					%else %do;
						if &maxorder1=0 then call define (_col_,"style","style=[fontstyle=italic]");
						else call define (_row_,"style","style=[background=libgr font_weight=bold bordertopcolor=black borderbottomcolor=black]");
					%end;
				end;
				else if &maxorder1=1 then call define(_col_,'style','style={indent=.15in}');
				else do;
					if sortorder2 = 0 then call define(_col_,'style','style={indent=.15in}');
					else if sortorder2 ne 0 then call define(_col_,'style','style={indent=.25in}');
				end;
            endcomp;

			/* Add title */
			compute before _page_ / style=[background=white font_weight=bold just=L foreground=black vjust=b bordertopcolor=black borderbottomcolor=black
                                           borderbottomwidth=&bordersize tagattr="wrap:no" cellheight=.3in];
            line "Table &tablenum.&tableletter.. &t5title. for &reporttitle. in the &database. from &startdateformatted. to &enddateformatted.&tabletitle.";
			endcomp;
          
            /*Add header rows*/
			%if &includeheaderrow. = Y %then %do;
            compute before header / style=[background=libgr foreground=black just=L font_weight=bold bordertopcolor=black bordertopwidth=1 borderbottomcolor=black]; 
				text = header;
				num = 100;
				line text $Varying. num;
            endcomp; 
			%end;

           /* Add Footnotes */
            %if %eval(&num_fn > 0) %then %do;
                compute after / style=[just=L borderbottomcolor=white bordertopcolor=black vjust=T fontsize=&footfontsize. bordertopwidth = &bordersize
                                       nobreakspace=off];
    		    %do f = 1 %to &num_fn.;
                line "^{super &f.}&&fn&f.";
    		    %end;
                endcomp;
            %end;
            %else %do;
                /*Add thick line to bottom of report*/
                compute after _page_ / style=[bordertopcolor=black bordertopwidth=&bordersize borderbottomcolor=white borderleftcolor=white borderrightcolor=white];
                line ' ';
                endcomp;
            %end;
        run;
	%end;	/* Continuous */
		
	%put =====> END MACRO: t5tables_output;

%mend;