****************************************************************************************************
*                                           PROGRAM OVERVIEW
****************************************************************************************************
*
* PROGRAM: t4tables_createdata.sas  
* Created (mm/dd/yyyy): 08/06/2021
*
*--------------------------------------------------------------------------------------------------
* PURPOSE: The macro produces tables for a Type 4 report
*                                        
*  Program inputs:                                                                                   
*   - agg_t4preg.sas7bdat   
*   - agg_t4nopreg.sas7bdat 
*   - agg_t4preggestwk.sas7bdat   
*   - agg_t4nopreggestwk.sas7bdat 
*
*  Program outputs:                                                                                                                           
*   - final_t4moi - levelid and moiname stratification across data partners
*   - final_dps_t4moi - levelid and moiname stratification by data partner
*   - final_t4gestwk - moiname and gestwk stratification across data partners
*   - final_dps_t4gestwk - moiname and gestwk stratification by data partner
* 
*  PARAMETERS: 
*   - dataset = suffix for input dataset indicator
*   - output_suffix = suffix for output dataset name
*   - episode_var: variable that holds # of pregnancy episodes
* 
*  Programming Notes:                                                                                 
*
*
*--------------------------------------------------------------------------------------------------
* CONTACT INFO: 
*  Sentinel Coordinating Center
*  info@sentinelsystem.org
*
***************************************************************************************************;

%macro t4tables_createdata(dataset = , output_suffix = , episode_var = );

    %put =====> MACRO CALLED: t4tables_createdata ;

   /*********************************************************************************************************
      Determine total count of variables on table and put tablecolumns information into macro variables
        - For tables T1-T4, there is a 1:1 relationship between rows in TABLECOLUMNS and columns in the table 
        - For tables T5-T6, TABLECOLUMNS only contains 3 possible columns, this table will be expanded for 
          each gestational week after table information is assigned to macro variables
    ********************************************************************************************************/
	proc sql noprint;
	  select distinct(compress(table)) into: tables separated by '" "'
      from tablefile where dataset in ("t4&dataset." "t4no&dataset.");
	  
	  select count(column) into: numcolumns trimmed
	  from tablecolumns where table in ("&tables.");
	  
	  select columnname 
	        ,column 
			,columnlabel
			,columnformat
			,scan(compress(column,'()'),1,'/') as numerator
			,case when index(column,'/') = 0 then ''
			   when index(column,'*')  > 0 then cats("den_",scan(compress(scan(column,1,'*'),'()'),2,'/')) 
			   else cats("den_",scan(column,2,'/')) end as denominator
			,case when index(columnformat,'$') > 0 then columnformat
			   else compress('$'||put(input(scan(compress(columnformat,'','a'),1,'.'),3.) +  input(scan(compress(columnformat,'','a'),2,'.'),3.),8.)||".") end as columnformatchar
	   into: var1 -:var&numcolumns.
		    ,:formula1 - :formula&numcolumns.
			,:label1 - :label&numcolumns.
			,:format1 - :format&numcolumns.
			,:num1 - :num&numcolumns.
			,:denominator1 - :denominator&numcolumns.
			,:formatchar1 - :formatchar&numcolumns.
	  from tablecolumns where table in ("&tables.");
	  
	  select distinct(a.numerator)
	         into: sumcolumns separated by " "
	        from (select case when index(column,'/') > 0 then scan(compress(column,'()'),1,'/')
                   else column end as numerator from tablecolumns where table in ("&tables.")) a;
    quit;

    /*Expand table to 1 row per gestional week*/
    %if &dataset. = preggestwk %then %do;

	    /* Identify min gestwk requested. Max always 44 weeks */
        data master_typefile;
            set master_typefile;
            length gestwk_min gestwk_max 3;
            if prepregdays >0 then gestwk_min = int((-prepregdays/7)-1); 
            else gestwk_min = 0; 
		    gestwk_max = 44;
        run;

        proc sql noprint;
		    select min(a.gestwk_min) into: min_min
            from master_typefile a,
                 groupsfile b
            where a.group = b.group;
        quit;

        %let max_max = 44; 

        data _temptablecolumns;
            set tablecolumns(where=(table in ('T5', 'T6')) rename=columnname=origcolumnname);
            spanningheader = columnlabel;
            /*negative weeks*/
            %if %eval(&min_min<0) %then %do;
            do i = %sysfunc(abs(&min_min.)) to 1 by -1;
                length columnname $32;
                /*change columnname to gestwk#column#*/
                columnname = cats('gestwkneg', i, origcolumnname);
                /*change columnlabel/columnheader (T6) to gestational week*/
                columnlabel = strip(cats('-',strip(put(i, best.))));
                if table = 'T6' then columnheader = strip(cats('-',strip(put(i, best.))));
                gestwkorder = i*-1;
                output;
            end;
            drop i;
            %end;

            /*Positive weeks*/
            do gestwkorder = 1 to &max_max.;
                length columnname $32;
                /*change columnname to gestwk#column#*/
                columnname = cats('gestwk', gestwkorder, origcolumnname);
                /*change columnlabel/columnheader (T6) to gestational week*/
                columnlabel = strip(put(gestwkorder, best.));
                if table = 'T6' then columnheader = strip(put(gestwkorder, best.));
                output;
            end;
        run;

        data tablecolumns;
            set tablecolumns(where=(table not in ('T5', 'T6')))
                _temptablecolumns;
        run;
    %end;

   /************************************************************************************************
     Identify substrat tables requested     
    ************************************************************************************************/
	 proc sql noprint;
	    select count(distinct tablesubstrat) into: numdset trimmed
		from tablefile where dataset in ("t4&dataset." "t4no&dataset.");
		
		select distinct tablesubstrat 
		   into: substrat1 - :substrat&numdset.
	    from tablefile where dataset in ("t4&dataset." "t4no&dataset.");
	 quit;

    /************************************************************************************************
      Assign default value for list of groups that assign pre pregnancy periods   
    ************************************************************************************************/
     %let prepreggrouplist =''; 
	 
	/************************************************************************************************
      Code specific for t4pregnancy and t4nopregnancy
	  - Identify levels 1 and 2 for preg and nopreg
	  - Calculate denominator episodes and denominator episodes in trimester 3
	  - Summarize data by group moiname and pregnancy flag for the identified level ids
     ************************************************************************************************/	
	 %if &dataset. = preg %then %do;
	
      /************************************************************************************************
        Determine levels
       ************************************************************************************************/	 
	    %let t4preglevel1 =;
	    %let t4preglevel2 =;
	    %let t4nopreglevel1 =;
	    %let t4nopreglevel2 =;
	    
	    %do ds = 1 %to &numdset.;
	      proc sql noprint;
             select distinct quote(levelid1), quote(levelid2) 
             into :&&&substrat&ds..level1,
                  :&&&substrat&ds..level2
             from tablefile where dataset = "&&substrat&ds.";
	      quit;
	    %end;
	  
     /************************************************************************************************
       Determine denominators for percent calculations          
      ************************************************************************************************/
        %macro t4_preg_nopreg (dsin = );	
	       proc sql noprint undo_policy=none;
	          create table _&dsin as 
                  select b.*
	              ,a.&episode_var. as den_&episode_var.
				  ,a.&episode_var._2trim as den_&episode_var._2trim
	              ,a.&episode_var._3trim as den_&episode_var._3trim
                  from agg_t4&dsin (keep = &episode_var. &episode_var._2trim &episode_var._3trim level group dpidsiteid 
	    		                    where=(level in (&&t4&dsin.level1))) as a,
                       agg_t4&dsin (where=(level in (&&t4&dsin.level2))) as b
                  where a.group=b.group 
	              and a.dpidsiteid = b.dpidsiteid;
           quit;
        %mend t4_preg_nopreg;
	    %if %sysfunc(findw(&datasetlist.,t4preg)) > 0 %then %do;
	      %t4_preg_nopreg(dsin = preg);
	    %end;
	    %if %sysfunc(findw(&datasetlist.,t4nopreg)) > 0 %then %do;
	       %t4_preg_nopreg(dsin = nopreg);
	    %end;
	  
     /************************************************************************************************
       Set preg and nopreg data together when requested for desired levels            
      ************************************************************************************************/
	     data _agg_t4moi;
	       length moiname $5;
	       set %if %sysfunc(findw(&datasetlist.,t4preg)) > 0 %then %do;
	             _preg (in = t4preg keep= dpidsiteid group moiname &sumcolumns &episode_var. &episode_var._2trim &episode_var._3trim den_:)
	    	   %end;
	    	   %if %sysfunc(findw(&datasetlist.,t4nopreg)) > 0 %then %do;
	    	     _nopreg (in = t4nopreg keep= dpidsiteid group moiname &sumcolumns &episode_var. &episode_var._2trim &episode_var._3trim den_:)
	    	   %end;;
	       if t4preg then pregflg = "Y";
	       else pregflg = "N";
	     run;
	  
     /************************************************************************************************
       List of groups with a defined pre-pregnancy period          
      ************************************************************************************************/
        %if %index(&sumcolumns., pre)>0 %then %do;
            proc sql noprint;
                select distinct "'"||group||"'" into: prepreggrouplist separated by ','
                from master_typefile
                where prepregdays >0;
            quit;
			%if %str("&prepreggrouplist") = %str("") %then %let prepreggrouplist = '';
        %end;
	  
     /************************************************************************************************
       Summarize Data     
      ************************************************************************************************/	
	    proc summary data = _agg_t4moi nway missing;
	      class group moiname pregflg;
	      var &sumcolumns. &episode_var. &episode_var._2trim &episode_var._3trim den_&episode_var. den_&episode_var._2trim den_&episode_var._3trim;
	      output out = _agg_t4moi_summ (drop = _:) sum=;
	    run;
	  %end; /* T4preg and T4nopreg specific code */
	  
	/************************************************************************************************
      Summarize preg and nopreg data by group moiname pregflg and gestational week
	   - Gestational week data is in a different format than pregnancy data and requires separate processing
     ************************************************************************************************/	
	  %else %do;
	    data _agg_t4moi (keep = group moiname gestwk pregflg dpidsiteid den_&episode_var. &sumcolumns. pregflg gestwk_char);
	      length pregflg $1 gestwk_char $15;
	      set %if %sysfunc(findw(&datasetlist.,t4preggestwk)) %then %do;
	  	      agg_t4preggestwk (in = preg)
	  		%end;
	  		%if %sysfunc(findw(&datasetlist.,t4nopreggestwk)) %then %do;
	  	      agg_t4nopreggestwk (in = nopreg)
	  		%end;;
	  	if gestwk < 0 then gestwk_char = left(cats("gestwkneg",put(abs(gestwk),3.)));
          else gestwk_char = left(cats("gestwk",put(gestwk,3.)));
	  	if preg then pregflg = "Y";
	      else pregflg = "N";
	  	den_&episode_var. = &episode_var.;
		if not (&min_min. <= gestwk <= &max_max.) then delete; /* remove gestational weeks not requested in the type4 file */
	    run;	
	  	
	    proc summary data = _agg_t4moi nway missing;
          class group moiname pregflg gestwk_char gestwk;
          var &sumcolumns. den_&episode_var.;
          output out = _agg_t4moi_summ (drop = _:) sum=;
        run;
		
		/*Determine the minimum gestional week for each group and assign to a macro variable*/
        proc sql noprint undo_policy=none;
           select distinct group into: group_list separated by ' '
           from _agg_t4moi;
        quit;

        data _null_;
          set master_typefile;
          %do g = 1 %to %sysfunc(countw(&group_list));
              if group = "%scan(&group_list, &g)" then call symputx("gestwk_group&g.", gestwk_min);
          %end;
        run;
	  %end;
	
   /************************************************************************************************
     Identify columns requested and apply labels and formats          
    ************************************************************************************************/ 
    %macro prep_t4tables (dsin =, dsout =, dpvar = );	
    	/* Join t4pregenrdays to dataset to be utilized as a condition for formatting */
    	proc sql noprint undo_policy=none;
    		create table &dsin as 
    		select a.* , b.t4pregenrdays, c.prepregdays
    		from &dsin a 
    		left join master_cohortfile b 
    		on a.group = b.cohortgrp
    		left join master_typefile c 
    		on a.group = c.group 
    		%if &dataset = preggestwk %then %do;
    		order by %if %length(&dpvar) %then %do; &dpvar, %end; group, moiname, pregflg ,gestwk_char
    		%end;
    		;
    		select distinct group into: cohort_list separated by ' ' from &dsin;
    	quit;

	   data &dsin. (keep = &dpvar. group moiname column: pregflg den_&episode_var. %if &dataset. = preggestwk %then %do; gestwk_char den_episodes_wk1 %end; %else %do; den_&episode_var._2trim den_&episode_var._3trim %end;);
	     set &dsin.;
		 /* Identify the total number of episodes at week 1 for gestational data. This is the max number of episodes in a cohort. */
		 %if &dataset. = preggestwk %then %do;
		   by &dpvar. group moiname pregflg gestwk_char;
		   retain den_episodes_wk1;
		   if first.pregflg and gestwk_char = "gestwk1" then den_episodes_wk1 = den_pregepisodes;
		 %end;
		 
		 %do vv = 1 %to &numcolumns;
		    label &&var&vv.. = "&&label&vv..";
			label &&var&vv.._char = "&&label&vv..";
			format &&var&vv.._char &&formatchar&vv..;
			
			%if %index(&&formula&vv.,/) > 0 %then %do;
               if &&num&vv. = . then &&num&vv. = 0;
			   if &&denominator&vv. <=0 then do;
			     &&var&vv. = .;
			   end;
			   else do;
			     &&var&vv. = &&num&vv./&&denominator&vv.;
			   end;
               &&var&vv.._char = strip(put(&&var&vv., &&format&vv..));
			%end;
			%else %do;
              if &&formula&vv. = . then &&formula&vv. = 0;
		      &&var&vv. = &&formula&vv.;
		      &&var&vv.._char = strip(put(&&var&vv., &&format&vv..));
			%end;
            
            /*standard missing value indicators*/
            /*if 0 patients in cohort, set to '.'*/
            if %if &dataset. = preg %then %do; den_&episode_var. <=0 %end; %else %do; den_episodes_wk1 <=0 %end; then do;
                &&var&vv. = .;
                &&var&vv.._char = '.';
            end;
            else do;
                /*if pre-pregnancy period not evaluated, set to 'N/A'*/
                %if %index(&&formula&vv.,pre)>0 and &dataset. = preg %then %do;
                    if group not in (&prepreggrouplist) then do;
                        &&var&vv.._char = 'N/A';
                        &&var&vv. = .;
                    end;
                %end;
                /* check each group and the pregnancy enrollment value value - set to N/A based on enrollment value */
                	%do i = 1 %to %sysfunc(countw(&cohort_list));
                		%let t4group = %scan(&cohort_list,&i);
                			%if &dataset = preg %then %do;
		                		%if %sysfunc(prxmatch(m/usepre|sumrawcntpre|sumadjcntpre/i,&&formula&vv.)) %then %do; 
		                			if lowcase(group) = "&t4group" and (-1*prepregdays) < t4pregenrdays <= 0 then do;
		                		   	&&var&vv.._char = 'N/A';
			                        &&var&vv. = .;
			                        &&var&vv.._ss=1;
			                    	end;
			                    %end;
		                		%if %sysfunc(prxmatch(m/usepre|sumrawcntpre|sumadjcntpre|anyt\b|anyt\/episodes\b|allt|anyt1|onlyt1|sumrawcntanyt1|sumadjcntanyt1|sumrawcntonlyt1|sumadjcntonlyt1/i,&&formula&vv.)) %then %do;
		                		    if lowcase(group) = "&t4group" and 0 < t4pregenrdays <= 97 then do; 
		                		    &&var&vv.._char = 'N/A';
			                        &&var&vv. = .;
			                        &&var&vv.._ss=1;
			                    	end;
		                		%end;
		                		%if %sysfunc(prxmatch(m/usepre|sumrawcntpre|sumadjcntpre|anyt\b|anyt\/episodes\b|allt|anyt1|onlyt1|anyt2|onlyt2|sumrawcntanyt1|sumadjcntanyt1|sumrawcntanyt2|sumadjcntanyt2|sumrawcntonlyt2|sumadjcntonlyt2/i,&&formula&vv.)) %then %do;
		                			if lowcase(group) = "&t4group" and 97 < t4pregenrdays <= 195 then do; 
		                		    &&var&vv.._char = 'N/A';
			                        &&var&vv. = .;
			                        &&var&vv.._ss=1;
			                        end;
			                    %end;
			                    %if %sysfunc(prxmatch(m/usepre|sumrawcntpre|sumadjcntpre|anyt\b|anyt\/episodes\b|allt|anyt1|onlyt1|anyt2|onlyt2|anyt3|onlyt3|sumrawcntanyt1|sumadjcntanyt1|sumrawcntonlyt1|sumadjcntonlyt1|sumrawcntonlyt2|sumadjcntonlyt2|sumrawcntanyt2|sumadjcntanyt2|sumrawcntonly3|sumadjcntonlyt3|sumrawcntanyt3|sumadjcntanyt3/i,&&formula&vv.)) %then %do;
		                			if lowcase(group) = "&t4group" and t4pregenrdays > 195 then do;   
			                        &&var&vv.._char = 'N/A';
			                        &&var&vv. = .;
			                        &&var&vv.._ss=1;
			                    	end;
		                    	%end;
		                    %end;
		                    %if &dataset = preggestwk %then %do;
		                        %if %sysfunc(prxmatch(m/moi/i,&&formula&vv.)) %then %do; 
		                        if lowcase(group) = "&t4group" then do; 
		                        	if t4pregenrdays < 0 and abs(int(t4pregenrdays/7)) < abs(gestwk) and gestwk < 0 then do;
		                        		&&var&vv.._char = 'N/A';
		                        		&&var&vv. = .;
		                        		&&var&vv.._ss=1;
			                        end;
		                        	else if t4pregenrdays >= 0 and int(t4pregenrdays/7) >= gestwk then do;
		                        		&&var&vv.._char = 'N/A';
		                        		&&var&vv. = .;
		                        		&&var&vv.._ss=1;
		                        	end;
		                        end;
		                        %end;
		                    %end;
		                    if lowcase(group) = "&t4group" and missing(t4pregenrdays) then do;
		                    		&&var&vv.._char = 'N/A';
		                        	&&var&vv. = .;
		                        	&&var&vv.._ss=1;
		                    end;
	                %end;
                /*if 0 episodes in 2nd/3rd trimester for preg/nopreg data or 0 episodes per week for gestational week data, % cannot be computed*/
                %if &&denominator&vv. = den_&episode_var._2trim | &&denominator&vv. = den_&episode_var._3trim | &&denominator&vv. = den_pregepisodes %then %do;
                    if &&denominator&vv. <=0 then &&var&vv.._char = 'NaN';
                %end;
            end;
	     %end;
	   run;

        /* transpose Data for gestwk from a long dataset (1 row per week) to a wide dataset (1 column per week) */
        %if &dataset. = preggestwk %then %do;
            /*Transpose both numeric and character vars*/
    		%do va = 1 %to &numcolumns; 
                proc transpose data = &dsin suffix = &&var&va.. out = &dsin._tran_&va.  (drop =_name_ _label_);
                   by &dpvar. group moiname pregflg den_episodes_wk1;
                   id gestwk_char;
                   var &&var&va..;
                run;
				
                proc transpose data = &dsin suffix = &&var&va.._char out = &dsin._tran_&va._char  (drop =_name_ _label_);
                   by &dpvar. group moiname pregflg den_episodes_wk1;
                   id gestwk_char;
                   var &&var&va.._char;
                run;

                proc transpose data = &dsin suffix = &&var&va.._ss out = &dsin._tran_&va._ss  (drop =_name_);
                   by &dpvar. group moiname pregflg den_episodes_wk1;
                   id gestwk_char;
                   var &&var&va.._ss;
                run;
            %end;
		 
		   /* Merge data for all columns */
		   data &dsin.;
             merge &dsin._tran_:;
		     by &dpvar. group moiname pregflg den_episodes_wk1;
			 /* set pre-pregnancy period to N/A for weeks that are less than the minimum gestational week per group */
			 %do g = 1 %to %sysfunc(countw(&group_list));      
			   %if &min_min. < &&&gestwk_group&g. %then %do;
			     if group = "%scan(&group_list., &g.)" then do;
			       %do min_loop = &min_min. %to &&&gestwk_group&g. -1;
                      %do vv = 1 %to &numcolumns; 
				  	    if den_episodes_wk1 > 0 then do;
                          gestwkneg%sysfunc(abs(&min_loop.))&&var&vv.._char = 'N/A';
                        end;
                        else do;
                          gestwkneg%sysfunc(abs(&min_loop.))&&var&vv.._char = '.';
                        end;
                      %end;
                   %end;
			     end;
			   %end;
			 %end;
           run;
        %end; /*gestational week table transpose*/
		
	   	/* Check if columns related to 2nd/3rd trimesters are requested */	    
		%let T2Columns=N;
		%let T3Columns=N;
		%if %index(%upcase(&sumcolumns.), ANYT2) | %index(%upcase(&sumcolumns.), ONLYT2) %then %let T2Columns=Y;
		%if %index(%upcase(&sumcolumns.), ANYT3) | %index(%upcase(&sumcolumns.), ONLYT3) %then %let T3Columns=Y;

	   /* Apply labels */
       proc sql noprint;
         create table &dsout. as
		 select all.*
         from(select a.*, b.order
		 %if &labelfileexists. = Y %then %do;
		 	,case %if &includeheaderrow = Y %then %do; when c.label = "" and d.label = "" then strip(a.group) %end;
			%if &dataset. = preg %then %do;
		 	        when c.label = "" then catx(' ',strip(a.group),"(" || %if &T2Columns. eq Y %then %do;strip(put(a.den_&episode_var._2trim,comma12.0))||" episodes reach the 2nd trimester, " || %end; %if &T3Columns. eq Y %then %do;strip(put(a.den_&episode_var._3trim,comma12.0))||" episodes reach the 3rd trimester, " || %end;strip(put(a.den_&episode_var.,comma12.0))||" total episodes)")
		 	   else catx(' ',strip(c.label),"(" || %if &T2Columns. eq Y %then %do;strip(put(a.den_&episode_var._2trim,comma12.0))||" episodes reach the 2nd trimester, " || %end; %if &T3Columns. eq Y %then %do;strip(put(a.den_&episode_var._3trim,comma12.0))||" episodes reach the 3rd trimester, " || %end;strip(put(a.den_&episode_var.,comma12.0))||" total episodes)") end as grouplabel 
		 	  ,case when d.label = "" then catx(' ',coalescec(c.label, a.group),strip(a.group),"(" || %if &T2Columns. eq Y %then %do;strip(put(a.den_&episode_var._2trim,comma12.0))||" episodes reach the 2nd trimester, " || %end; %if &T3Columns. eq Y %then %do;strip(put(a.den_&episode_var._3trim,comma12.0))||" episodes reach the 3rd trimester, " || %end;strip(put(a.den_&episode_var.,comma12.0))||" total episodes)")
			%end;
			%else %do;
			       when c.label = "" then strip(a.group)
		 	   else strip(c.label) end as grouplabel 
		 	  ,case when d.label = "" then coalescec(c.label, a.group)
			%end;
             else d.label end as header
            ,case when e.label = "" then a.moiname
             else e.label end as moilabel 
		       	,case when f.label = "" then a.moiname
             else f.label end as moiheader 
		 %end;
         %else %do;
		    %if &dataset. = preg %then %do;
		      ,catx(' ',strip(a.group),"(" || %if &T2Columns. eq Y %then %do;strip(put(a.den_&episode_var._2trim,comma12.0))||" episodes reach the 2nd trimester, " || %end; %if &T3Columns. eq Y %then %do;strip(put(a.den_&episode_var._3trim,comma12.0))||" episodes reach the 3rd trimester, " || %end;strip(put(a.den_&episode_var.,comma12.0))||" total episodes)") as grouplabel  
			%end;
			%else %do;
			  ,strip(a.group) as grouplabel
			%end;
            ,a.moiname as moilabel
            ,"" as moiheader 
         %end;				   
             from &dsin. a 
		      left join groupsfile b
		      on strip(lowcase(a.group)) = strip(lowcase(b.group))
		      %if &labelfileexists. = Y %then %do;
		        left join labelfile (where = (labeltype = "grouplabel")) c
		        on strip(a.group) = strip(c.group)
		        left join labelfile (where = (labeltype = "header")) d
		        on strip(a.group) = strip(d.group)
		     	left join labelfile (where = (labeltype = "moilabel")) e
		     	on strip(a.group) = strip(e.group)
		     	 and lowcase(a.moiname) = strip(e.labelvar)
		     	left join labelfile (where = (labeltype = "moiheader")) f
		     	on strip(a.group) = strip(f.group)
		     	 and lowcase(a.moiname) = strip(f.labelvar)
		      %end;) all;
        quit;
		
		proc sort data = &dsout. sortseq=linguistic(numeric_collation=on);
		  by descending pregflg order moiname;
		run;
    %mend;

	/*Overall*/
    %prep_t4tables (dsin=_agg_t4moi_summ, dsout=final&output_suffix.);

	/*By Data Partner*/
    %if &stratifybydp. = Y %then %do;
	  %prep_t4tables(dsin=_agg_t4moi, dsout=final_dps&output_suffix., dpvar=dpidsiteid);
	%end;
	
	/*Clean up*/
    proc datasets nowarn noprint lib=work;
      delete _:;
    quit;

    %put =====> END MACRO: t4tables_createdata ;

%mend t4tables_createdata;