libname MACRO '[]';
option mstored sasmstore=MACRO;

%macro CATE(        /* ANALYSIS OF CATEGORICAL VARIABLE         */
            DESC=1, /* Descriptive parameter (0=no,1=yes)       */
            ANAL=1, /* Analytical parameter  (0=no,1=yes)       */
            NCAT=,  /* Number of categories                     */
            RCAT=1, /* Reference Category                       */
            QVAR=,  /* Categorical variable                     */
            TITL=,  /* Variable label                           */
            LBL1=,  /* Value label for 1st category             */
            LBL2=,  /* Value label for 2nd category             */
            LBL3=,  /* Value label for 3rd category             */
            LBL4=,  /* Value label for 4th category             */
            LBL5=,  /* Value label for 5th category             */
            LBL6=,  /* Value label for 6th category             */
            LBL7=,  /* Value label for 7th category             */
            LBL8=,  /* Value label for 8th category             */
            LBL9=   /* Value label for 9th category             */
           ) /Store;

   /* Create a Subset of the data                               */
data DSET;
 set &DSET(Keep=&IDNUM &QVAR &STAT &BASELIN &SUBSET);
 where (&SUBSET=1);

   /*  Generate Dummy variables for Logistic regression         */
   /*  Associate labels                                         */
 QVAR1=(&QVAR=&RCAT); 
 %do i=2 %to &NCAT;
     QVAR&i=(&QVAR=&i); label QVAR&i="&LBL&i";
 %end;

 QVAR&RCAT=(&QVAR=1); 
 label QVAR&RCAT="&LBL1";
 VALID=(&QVAR^=. and &QVAR>0 and &QVAR<=&NCAT); 
 label VALID="Valid &TITL";
 run;

   /*  Define value labels using the procedure Format           */
proc format; 
 value LBL_lbl %do i = 1 %to &NCAT; 
                   &i="&LBL&i" 
               %end; ;
 value CC_lbl 1='Case' 2='Control';
run;
title1 
"=================================================================
================================================================="
;
title2 ">>> &TITL <<<   &STUDY   &SYSDAY &SYSDATE, &SYSTIME     ";
title3 
"=================================================================
================================================================="
;
title4 ">>> Selection &SUBTITL <<< ";

   /* Descriptive parameter set to 1                            */
%if &DESC = 1 %then %do;

 title5 ">>> Tabulation <<<";
 proc tabulate data=DSET noseps missing format=7.0;
  keylabel N='Count' PCTN='Percent';
  format &STAT CC_lbl. &QVAR LBL_lbl.; 
  class &STAT &QVAR;
  table (&QVAR),(ALL &STAT*(N PCTN<&QVAR>*F=8.2))/rts=36;
 run;
 title5 ">>> Possible abnormal values ?... <<<";
 proc print data=DSET noobs;
  var &IDNUM &QVAR;
  where ((&QVAR ^=. and &QVAR <1) or &QVAR > &NCAT);
 run;
%end;

   /* Analytical parameter set to 1                             */
%if &ANAL = 1 %then %do;
 title5 ">>> Logistic regression (categorical variable) <<<";
 title6 ">>> Reference group : &&LBL&RCAT <<<";
 proc logistic data=DSET;
  freq VALID;
  model &STAT= %do i=2 %to &NCAT;
                   QVAR&i
               %end;
               &BASELIN /rl;
 run;
%end;

title1;title2;title3;title4;title5;title6;
%mend CATE;


%macro CONT(        /* ANALYSIS OF CONTINUOUS VARIABLES         */
            DESC=1, /* Descriptive parameter (0=no,1=yes) */
            ANAL=1, /* Analytical parameter  (0=no,1=yes) */
            NCAT=3, /* Number of Categories               */
            CVAR=,  /* Continuous variable                */
            TITL=   /* Variable label                     */
           ) /Store ;

   /*   Create a subset of the data, define value labels        */
data DSET; 
 set &DSET(Keep=&IDNUM &CVAR &STAT &BASELIN &SUBSET);
 where (&SUBSET=1);
 ELIG=(&CVAR^=.); 
run;

proc format; 
 value CC_lbl 1='Case' 2='Control'; 
run;

title1 
"=================================================================
================================================================="
;
title2 ">>> &TITL <<<   &STUDY   &SYSDAY &SYSDATE, &SYSTIME     ";
title3 
"=================================================================
================================================================="
;
title4 ">>> Selection &SUBTITL <<< ";

   /* Descriptive-parameter set to 1                            */
%if &DESC = 1 %then %do;
 title5 ">>> Univariate procedure <<<";
 proc sort data=DSET;
  by &STAT; 
 run;

 proc univariate Data=DSET plot; 
  var &CVAR; 
  format &STAT CC_lbl.; 
  by &STAT; 
 run;

 proc univariate data=DSET noprint; 
  var &CVAR; 
  output out=TMP mean=MExx std=STxx; 
 run;

 data WORK; 
  if _n_=1 then set TMP; 
  set DSET;
 run;
 title5 ">>> Possible abnormal small values ?... <<<";

 proc print data=WORK noobs; 
  var &IDNUM &CVAR; 
  where &CVAR < MExx-3*STxx and &CVAR^=.; 
 run;

 title5 ">>> Possible abnormal large values ?... <<<";
 proc print data=WORK noobs; 
  var &IDNUM &CVAR; 
  where &CVAR > MExx+3*STxx; 
 run;
%end;

   /* Analytical parameter set to 1                             */
%if &ANAL = 1 %then %do;
 proc rank data=DSET groups=&NCAT out=RANK; 
  var &CVAR; 
  ranks RVAR; 
 run;

 proc univariate data=DSET noprint; 
  var &CVAR; 
  output out=CUTP 
         pctlpts= %do i=1 %to %eval(&NCAT-1); 
                      %eval(&i*100/&NCAT)
                  %end;
         pctlpre=VARC; 
 run;

 title5 ">>> Logistic regression (continuous variable) <<<";
 proc logistic data=DSET; 
  freq ELIG; 
  model &STAT=&CVAR &BASELIN /rl; 
 run;

 data WORK; 
  if _n_=1 then set CUTP; 
  set RANK;
  RVAR=RVAR+1; 
  %do i=2 %to &NCAT; 
      RVAR&i=(RVAR=&i); 
  %end;

  if RVAR=1 then QVAR="Q1: Less than "||
     left(put(VARC%eval(100/&NCAT),8.1));
  %do i=2 %to %eval(&NCAT-1);
      if RVAR=&i then QVAR="Q&&i: "||
         trim(left(put(VARC%eval((&i-1)*100/&NCAT),8.1)))||
         " to "||left(PUT(VARC%eval(&i*100/&NCAT),8.1));
  %end;
  if RVAR=&NCAT then QVAR="Q&&NCAT: "||
     trim(left(put(VARC%eval((&NCAT-1)*100/&NCAT),8.1)))||
     " or more";
  label RVAR = "&TITL (ordinal)"
        QVAR = "&TITL"
        %do i=2 %to &NCAT;
            RVAR&i= "Q&i &TITL"
        %end;
 ;

 run;

 title5 ">>> Tabulation <<<";
 proc tabulate data=WORK noseps missing format=7.0;
  keylabel N='Count' PCTN='Percent';
  format &STAT CC_lbl.; 
  class &STAT QVAR;
  table QVAR,(ALL &STAT*(N PCTN*F=8.2))/rts=36;
 run;

 title5 ">>> Logistic regression (ordinal variable) <<<";
 proc logistic data=WORK; 
  freq ELIG; 
  model &STAT=RVAR &BASELIN /rl; 
 run;

title5 ">>> Logistic regression (categorical variable) <<<";
 proc logistic data=WORK; 
  freq ELIG; 
  model &STAT=%do i=2 %to &NCAT;
                  RVAR&i
              %end; 
              &BASELIN /rl;
 run;
%end;
title1;title2;title3;title4;title5;
%mend CONT;