Statistical Analysis¶

Dependent Variable (All Endpoints)¶

For each endpoint, the dependent variable will be Change from Vehicle, defined for each animal and time interval on Dosing Day 3 (including baseline) as:

[ \text{Change from Vehicle} = \big(\text{Value at Day 3, time } t\big) - \big(\text{Value at Vehicle Day 1, same time } t\big) ]

Study-Day Phases¶

Data will be analyzed by study-day phase:

  • Phase 1: Hours 1–6 (six 1-hour subphases)
  • Phase 2: Hours 7–12 (six 1-hour subphases)
  • Phase 3: Hours 13–18 (six 1-hour subphases)
  • Phase 4: Hours 19–24 (six 1-hour subphases)

Model (Within Phase)¶

Within each phase, a repeated-measures ANCOVA (RANCOVA) will be fit using PROC MIXED, with:

  • Fixed effects: TRT, TIME, and TRT×TIME
  • Covariate: baseline Change from Vehicle
  • Repeated effect: TIME
  • Subject: SUBJID

The covariance structure will be selected using AICC across candidate covariance structures.

Hypothesis Testing¶

For each treatment group, the null hypothesis will be tested at the 0.05 significance level at each time interval:

[ H_0: \text{Change from Vehicle} = 0 ]

Macro: RANCOVA_PARALLEL¶

Objective¶

Run a repeated-measures ANCOVA / MMRM in PROC MIXED for each PARAMCD and PHASE, using a user-specified within-subject covariance structure, and save key outputs to datasets for easy comparison across covariance types.


Model (fixed effects)¶

[ \text{CHANGE} = \text{BASE} + \text{DOSE} + \text{SUBPHASE} + (\text{DOSE} \times \text{SUBPHASE}) ]


Key questions answered¶

  1. Is there evidence of a treatment-by-time interaction?
    Type 3 test for DOSE*SUBPHASE
  2. What are the model-based means over time by dose?
    LSMeans for DOSE*SUBPHASE
  3. Which covariance structure fits best?
    AICC from FitStatistics (used for comparing TYPE choices)

Parameters¶

  • type=
    Covariance structure for the REPEATED statement.
    Examples: CS, CSH, AR(1), ARH(1), UN, TOEP, SP(POW), etc.
    Note: Parentheses in type are removed for dataset naming
    (e.g., SP(POW) → SPPOW).

  • random=
    Optional RANDOM statement(s) inserted verbatim into PROC MIXED.
    Use for random intercept/slope models when appropriate.
    Example: random intercept / subject=subjid;
    Leave blank to fit a pure repeated-measures model.


Input data requirements (MYDATA)¶

Your dataset must contain:

  • PARAMCD, PHASE (BY variables)
  • SUBJID (subject identifier)
  • DOSE (treatment/dose group)
  • SUBPHASE (visit/time variable)
  • CHANGE (response)
  • BASE (baseline covariate)

Sorting requirement:
Because BY-processing is used, the data must be sorted by:

  • PARAMCD, PHASE

Outputs (ODS OUTPUT datasets)¶

For each covariance structure type, the macro creates:

  • <type>.TESTS
    Type 3 tests filtered to the interaction (DOSE*SUBPHASE), plus TYPE label

  • <type>.LSM
    LSMeans for DOSE*SUBPHASE, plus TYPE label

  • <type>.FIT
    FitStatistics filtered to AICC, plus TYPE label


Notes¶

  • type is “cleaned” (parentheses removed) after the PROC MIXED step to ensure valid dataset names.
  • The Type 3 filter uses Effect="*SUBPHASE" which matches "DOSE*SUBPHASE".
  • The fit row retained is: AICC (Smaller is Better).
    You can switch to AIC/BIC by changing the `WHER
In [ ]:

In [48]:
options nonotes nosource nosource2 nomprint nomlogic nosymbolgen;

/***********Format for p values*************************************************/
proc format;
   picture psignif (round) low-0.001='<.001*' (noedit) 0.001<-<0.05='0009.999*' 0.05-1='0009.999';
run;


proc format; 
   invalue param (notsorted) "HR" = 1 "PP" = 2 "SAP"= 3 "DAP"= 4 "MAP"= 5; 
     value dayx (notsorted) 1 = "Day 1"  3= "Day 3"; 
run;

*  Format used *****************************************;
%let STATFMT0D=12.;
%let STATFMT1D=%sysevalf(&STATFMT0D + 0.1);
%let STATFMT2D=%sysevalf(&STATFMT1D + 0.1);
%let STATFMT3D=%sysevalf(&STATFMT2D + 0.1);
%let STATFMT4D=%sysevalf(&STATFMT3D + 0.1);
%let STATFMT5D=%sysevalf(&STATFMT4D + 0.1);


* rounding *********************************************;
%let round1 =0.1;
%let round2 =%sysevalf(0.1*&round1);
%let round3 =%sysevalf(0.1*&round2);
%let round4 =%sysevalf(0.1*&round3);
%let round5 =%sysevalf(0.1*&round4);

%put &STATFMT1D &STATFMT2D &STATFMT3D &STATFMT4D &STATFMT5D 
     &round1 &round2 &round3 &round4 &round5;

/*******************************************************/
12.1 12.2 12.3 12.4 12.5       0.1 0.01 0.001 0.0001 0.00001

Read ADSX from SASDATA library into WORK and print first 10 rows

In [4]:
libname sasdata "/export/viya/homes/alpha@alphatraore.com/toydata";

data adsx;
    set sasdata.adsx;
run;

proc print data =adsx (obs=10); run;
SAS Output

The SAS System

Obs SUBJID PARAMCD PERIOD PHASE SUBPHASE TIME DOSE VALUE VEHICLE CHANGE BASE
1 4429843 HR 1 0 1 0 1 59.803 59.740 0.063 .
2 4429843 HR 1 1 1 1 1 136.792 70.102 66.690 0.063
3 4429843 HR 1 1 2 2 1 146.995 51.557 95.438 0.063
4 4429843 HR 1 1 3 3 1 144.255 62.700 81.555 0.063
5 4429843 HR 1 1 4 4 1 131.402 56.043 75.359 0.063
6 4429843 HR 1 1 5 5 1 133.367 56.759 76.608 0.063
7 4429843 HR 1 1 6 6 1 118.239 48.994 69.245 0.063
8 4429843 HR 1 2 1 7 1 99.816 61.676 38.140 0.063
9 4429843 HR 1 2 2 8 1 104.273 47.869 56.404 0.063
10 4429843 HR 1 2 3 9 1 107.491 50.444 57.047 0.063

Exclude baseline (TIME=0) and sort by PARAMCD and PHASE for BY-group analyses

In [ ]:
/* Baseline dataset (TIME=0) and Sort for BY paramcd phase */ */
data mybase;
     set adsx;
     where time=0;
run;
proc sort; by paramcd phase  ;  run;


/* Baseline LSMeans by DOSE within PARAMCD/PHASE */
proc mixed data=mybase;
        by paramcd phase;
        class dose;
        model CHANGE = DOSE ;
        LSMEANS DOSE;
        ods output
        LSMeans = lsm_base
        ;
run;

/* Add baseline subphase flag */
data baselsm;
        set lsm_base;
        SUBPHASE=1;
run;
In [ ]:

In [56]:
/* Create analysis dataset excluding baseline (TIME ≠ 0) */
data mydata;
     set adsx;
     where time^=0;
run;

/* Sort for subsequent BY-group analyses (PARAMCD, PHASE) */
proc sort; by paramcd phase  ;  run;

%macro RANCOVA_PARALLEL(type=, random= );

proc mixed data=mydata;
       by paramcd phase ; 
       class subjid dose subphase; 

       model change = base dose subphase dose*subphase; 
       &random
       repeated SUBPHASE / type=&type sub=subjid;
       lsmeans DOSE*SUBPHASE ;
       %let type = %sysfunc(compress(%superQ(type),%str(%(%))));

       ods output
       Tests3 =&type.tests (where=(Effect="*SUBPHASE"))
       LSMeans = &type.lsm
       FitStatistics =&type.Fit
;
run;

data &type.Fit (drop=Descr);
     set &type.Fit;
     length type $15;
     /*    where=(Descr="AIC (Smaller is Better)");*/
     where Descr="AICC (Smaller is Better)";
     type="&type.   ";
run;


data &type.tests ;
     set &type.tests;
     length type $15;
     type="&type.   ";
run;

data &type.lsm ;
     set &type.lsm;
     length type $15;
     type="&type.   ";
run;

%mend RANCOVA_PARALLEL;

In [58]:
ods results off;
ods select none;
ods exclude all;
ods graphics off;

/***************************************************************/
%RANCOVA_PARALLEL(type=CS)
%RANCOVA_PARALLEL(type=CSH)

%RANCOVA_PARALLEL(type=AR(1) , random=%str(random subjid;))
%RANCOVA_PARALLEL(type=ARH(1), random=%str(random subjid;) )

ods results on; 
ods select all; 
ods exclude none; 
ods graphics on;
SAS Output
In [59]:
/****************** Checking the fit to select the best model****/
data fitdata;
     set Csfit Cshfit Ar1fit  Arh1fit;
run;

proc sort data=fitdata; by paramcd phase value; run;

data bestfit;
     set fitdata;
    by paramcd phase value;
     if first.phase;
run;
proc sort; by paramcd phase type; run;

/*************Stack the data and select the best************/
data lsm; set Cslsm Cshlsm Ar1lsm Arh1lsm ; run;
proc sort; by paramcd phase  type; run;

data lsm_s;
     merge lsm (in=a) bestfit (in=b);
     by paramcd phase  type;
     if  a and b;
run;

data A_lsm_s;
     set lsm_s baselsm;
run;


proc sort data=A_lsm_s; by paramcd   phase SUBPHASE; run;

data report_lsm_ (rename=(dose=trtn SUBPHASE=atptn));
     set A_lsm_s;
     length rownum 8 rowlbl $40 cell $20; 
     retain  rownum;
     by paramcd   phase SUBPHASE;
     rownum =4;
          rowlbl = 'LSM';
          if abs(Estimate) < 10 then cell   = strip(put(round(Estimate,&round4), &STATFMT4D));
          else if 10 =< abs(Estimate) < 100 then cell   = strip(put(round(Estimate,&round3), &STATFMT3D));
          else if 100 =< abs(Estimate) < 1000 then cell   = strip(put(round(Estimate,&round2), &STATFMT2D));
          else if abs(Estimate) =< 1000 then cell   = strip(put(round(Estimate,&round1), &STATFMT1D));
     output;
     rownum +1;
          rowlbl = 'LSM s.e.';
          if abs(Estimate) < 10 then cell   = strip(put(round(StdErr,&round5), &STATFMT5D));
          else if 10 =< abs(Estimate) < 100 then cell   = strip(put(round(StdErr,&round4), &STATFMT4D));
          else if 100 =< abs(Estimate) < 1000 then cell   = strip(put(round(StdErr,&round3), &STATFMT3D));
          else if abs(Estimate) =< 1000 then cell   = strip(put(round(StdErr,&round2), &STATFMT2D));
     output;
     keep paramcd PHASE DOSE SUBPHASE rownum rowlbl cell;
run;

data report_lsm;
     set report_lsm_;
     if missing(atptn) then atptn=999;
run;

In [61]:
proc sort data=A_lsm_s (rename=(dose=trtn SUBPHASE=atptn)) out=A_lsm_ss ; by paramcd phase  atptn trtn ; run;

data report_lsmPv ;
     set A_lsm_ss;
     length rownum 8 rowlbl $40 cell $20; 
     retain  rownum;
     
     by paramcd phase  atptn trtn ;
     rownum =6;
          rowlbl = 'LSM = 0 p-value     ';
          cell   = strip(strip(put(Probt,psignif.)));
     output;
     keep paramcd phase  rownum rowlbl cell atptn trtn;
run;

In [63]:
ods results off;
ods select none;
ods exclude all;
ods graphics off;

/********************************************************/
*  Create the statistics for Section 1 of the report;
proc summary print data=adsx missing stackods 
             n mean std;
  class paramcd  dose phase SUBPHASE;
  var CHANGE;
  ods output Summary=bySUBPHASE;
run; quit;

proc summary print data=adsx (where=(PHASE^=0)) missing stackods   
             n mean std;
  class subjid paramcd  dose phase;
  var CHANGE;
  ods output Summary=tempsum;
run; quit;


proc summary print data=tempsum missing stackods    
             n mean std;
  class paramcd  dose phase;
  var Mean;
  ods output Summary=overall;
run; quit;

data summary;
     set bySUBPHASE overall;
     if missing(SUBPHASE) then SUBPHASE=999;
run;

proc sort data=summary; by paramcd  dose phase SUBPHASE; run;  

*;
*  Create a separate row from specific column values of the 
*  Summary data - Section 1.
*;

data report_summary_ (rename=(SUBPHASE=atptn dose=trtn));
     set work.summary;
     length rownum 8 rowlbl $40 cell $20; 
     retain  rownum;
     section = 1;
     by paramcd  dose phase SUBPHASE;
     rownum =1;
          rowlbl = 'Mean Change from Vehicle';
          if abs(mean) < 10 then cell   = strip(put(round(mean,&round4), &STATFMT4D));
          else if 10 =< abs(mean) < 100 then cell   = strip(put(round(mean,&round3), &STATFMT3D));
          else if 100 =< abs(mean) < 1000 then cell   = strip(put(round(mean,&round2), &STATFMT2D));
          else if abs(mean) =< 1000 then cell   = strip(put(round(mean,&round1), &STATFMT1D));
     output;
     rownum +1;
          rowlbl = 'SD';
          if abs(mean) < 10 then cell   = strip(put(round(StdDev,&round5), &STATFMT5D));
          else if 10 =< abs(mean) < 100 then cell   = strip(put(round(StdDev,&round4), &STATFMT4D));
          else if 100 =< abs(mean) < 1000 then cell   = strip(put(round(StdDev,&round3), &STATFMT3D));
          else if abs(mean) =< 1000 then cell   = strip(put(round(StdDev,&round2), &STATFMT2D));
     output;

     rownum +1;
     rowlbl = 'N';
     cell   = strip(put(N, &STATFMT0D));
     output;

     keep paramcd phase  rownum rowlbl cell SUBPHASE dose; ;
run;
data report_summary;
     set report_summary_;
     if atptn=999 and rownum=2 then cell="NA";
run;


/*****************Stack for report *********************/

data tempdata1 (where=(phase^=0));
     set Report_lsmPv Report_lsm report_summary;
     if missing(atptn) then atptn=999;
     paramn=input(paramcd,param.);
run;

proc sort ; by paramcd paramn phase  trtn rownum rowlbl atptn;run;


*  Transpose the data to get the layout needed for the report for post dose ;

proc transpose data=tempdata1 prefix=time_
               out=report_post (drop=_name_);
  by paramcd paramn phase  trtn rownum rowlbl;
  var cell;
  id atptn;
run; 


/***********base****************/
data tempdata2 (where=(phase=0));
     set Report_lsmPv Report_lsm report_summary;
     paramn=input(paramcd,param.);
     atptn=0;
run;

proc sort ; by paramcd paramn phase  trtn rownum rowlbl atptn;run;


*  Transpose the data to get the layout needed for the report for pre dose;

proc transpose data=tempdata2 prefix=time_
               out=report_base_ (drop=_name_);
  by paramcd paramn phase  trtn rownum rowlbl;
  var cell;
  id atptn;
run; 

data report_base;
     set report_base_;
     phase=1;
run;

/******all the table ***********************/

data reportfinal;
     merge report_base report_post;
     by paramcd paramn phase  trtn rownum rowlbl;
run;

ods results on; 
ods select all; 
ods exclude none; 
ods graphics on; 

proc print data=reportfinal; run;
SAS Output
Obs PARAMCD paramn PHASE trtn rownum rowlbl time_0 time_1 time_2 time_3 time_4 time_5 time_6 time_999
1 HR 1 1 1 1 Mean Change from Vehicle -5.6808 32.887 65.620 62.210 62.277 50.920 51.484 54.233
2 HR 1 1 1 2 SD 5.35020 26.4502 22.4734 14.2521 10.7755 18.2817 12.4820 NA
3 HR 1 1 1 3 N 4 4 4 4 4 4 4 4
4 HR 1 1 1 4 LSM -5.6808 33.494 66.227 62.817 62.885 51.528 52.091  
5 HR 1 1 1 5 LSM s.e. 3.53068 9.4020 8.6803 6.5935 6.3018 7.3207 4.3766  
6 HR 1 1 1 6 LSM = 0 p-value 0.142 <.001* <.001* <.001* <.001* <.001* <.001*  
7 HR 1 1 2 1 Mean Change from Vehicle 0.4820 2.8933 30.080 28.284 21.067 21.256 15.926 19.917
8 HR 1 1 2 2 SD 8.79171 18.32200 16.4893 13.7110 13.1081 7.0977 3.4467 NA
9 HR 1 1 2 3 N 4 4 4 4 4 4 4 4
10 HR 1 1 2 4 LSM 0.4820 2.7469 29.933 28.137 20.920 21.109 15.779  
11 HR 1 1 2 5 LSM s.e. 3.53068 9.29278 8.5619 6.4368 6.1377 7.1799 4.1368  
12 HR 1 1 2 6 LSM = 0 p-value 0.894 0.769 0.001* <.001* 0.001* 0.005* <.001*  
13 HR 1 1 3 1 Mean Change from Vehicle 3.0553 -10.479 24.696 23.208 22.907 29.218 20.813 18.394
14 HR 1 1 3 2 SD 6.60833 12.5510 16.7581 14.0077 13.3197 12.5136 2.3645 NA
15 HR 1 1 3 3 N 4 4 4 4 4 4 4 4
16 HR 1 1 3 4 LSM 3.0553 -10.940 24.235 22.747 22.446 28.757 20.351  
17 HR 1 1 3 5 LSM s.e. 3.53068 9.3530 8.6273 6.5235 6.2285 7.2577 4.2704  
18 HR 1 1 3 6 LSM = 0 p-value 0.409 0.248 0.007* 0.001* <.001* <.001* <.001*  
19 HR 1 2 1 1 Mean Change from Vehicle   21.215 40.394 45.012 28.181 39.603 32.725 34.522
20 HR 1 2 1 2 SD   13.3448 11.3117 8.6502 15.2532 16.0131 13.4334 NA
21 HR 1 2 1 3 N   4 4 4 4 4 4 4
22 HR 1 2 1 4 LSM   25.729 44.907 49.526 32.695 44.116 37.238  
23 HR 1 2 1 5 LSM s.e.   6.0514 3.7927 2.9337 7.5557 5.8270 5.3551  
24 HR 1 2 1 6 LSM = 0 p-value   <.001* <.001* <.001* <.001* <.001* <.001*  
25 HR 1 2 2 1 Mean Change from Vehicle   1.8203 12.587 15.388 15.828 20.142 6.5480 12.052
26 HR 1 2 2 2 SD   9.84040 5.4118 7.9559 8.1258 4.0932 6.66645 NA
27 HR 1 2 2 3 N   4 4 4 4 4 4 4
28 HR 1 2 2 4 LSM   0.7328 11.499 14.300 14.740 19.054 5.4605  
29 HR 1 2 2 5 LSM s.e.   5.93683 3.6072 2.6896 7.4643 5.7080 5.22531  
30 HR 1 2 2 6 LSM = 0 p-value   0.902 0.003* <.001* 0.054 0.002* 0.302  
31 HR 1 2 3 1 Mean Change from Vehicle   1.7793 17.523 12.252 25.109 29.862 29.819 19.391
32 HR 1 2 3 2 SD   11.12709 8.5156 5.7771 12.6284 9.3523 9.2791 NA
33 HR 1 2 3 3 N   4 4 4 4 4 4 4
34 HR 1 2 3 4 LSM   -1.6469 14.097 8.8256 21.683 26.436 26.392  
35 HR 1 2 3 5 LSM s.e.   6.00010 3.7104 2.82648 7.5147 5.7738 5.2971  
36 HR 1 2 3 6 LSM = 0 p-value   0.785 <.001* 0.003* 0.006* <.001* <.001*  
37 HR 1 3 1 1 Mean Change from Vehicle   27.859 27.505 23.308 24.550 20.126 19.665 23.835
38 HR 1 3 1 2 SD   8.6534 6.6541 6.2420 9.5938 11.1809 6.0945 NA
39 HR 1 3 1 3 N   4 4 4 4 4 4 4
40 HR 1 3 1 4 LSM   29.810 29.456 25.258 26.500 22.076 21.615  
41 HR 1 3 1 5 LSM s.e.   3.4445 3.4445 3.4445 3.4445 3.4445 3.4445  
42 HR 1 3 1 6 LSM = 0 p-value   <.001* <.001* <.001* <.001* <.001* <.001*  
43 HR 1 3 2 1 Mean Change from Vehicle   9.3565 -1.9355 1.7350 0.4398 -2.4290 -1.0460 1.0201
44 HR 1 3 2 2 SD   7.65104 8.17044 4.23825 10.18202 3.74822 2.86982 NA
45 HR 1 3 2 3 N   4 4 4 4 4 4 4
46 HR 1 3 2 4 LSM   8.8866 -2.4054 1.2651 -0.0301 -2.8989 -1.5159  
47 HR 1 3 2 5 LSM s.e.   3.31740 3.31740 3.31740 3.31740 3.31740 3.31740  
48 HR 1 3 2 6 LSM = 0 p-value   0.010* 0.472 0.705 0.993 0.387 0.650  
49 HR 1 3 3 1 Mean Change from Vehicle   21.028 16.797 13.002 3.8520 7.8570 12.371 12.484
50 HR 1 3 3 2 SD   7.9806 4.4917 6.5361 4.56616 3.95595 7.0126 NA
51 HR 1 3 3 3 N   4 4 4 4 4 4 4
52 HR 1 3 3 4 LSM   19.547 15.316 11.522 2.3715 6.3765 10.890  
53 HR 1 3 3 5 LSM s.e.   3.3879 3.3879 3.3879 3.38788 3.38788 3.3879  
54 HR 1 3 3 6 LSM = 0 p-value   <.001* <.001* 0.001* 0.488 0.066 0.002*  
55 HR 1 4 1 1 Mean Change from Vehicle   20.720 16.689 18.946 13.566 7.0670 -2.5748 12.402
56 HR 1 4 1 2 SD   4.6006 6.4045 7.8181 9.8952 9.91546 11.55177 NA
57 HR 1 4 1 3 N   4 4 4 4 4 4 4
58 HR 1 4 1 4 LSM   22.507 18.476 20.733 15.353 8.8541 -0.7876  
59 HR 1 4 1 5 LSM s.e.   3.6550 3.6550 3.6550 3.6550 3.65504 3.65504  
60 HR 1 4 1 6 LSM = 0 p-value   <.001* <.001* <.001* <.001* 0.020* 0.830  
61 HR 1 4 2 1 Mean Change from Vehicle   -0.4255 -7.6510 -4.3090 -7.0170 -11.966 -11.977 -7.2242
62 HR 1 4 2 2 SD   6.44556 7.24202 5.87769 4.53746 7.5879 5.5382 NA
63 HR 1 4 2 3 N   4 4 4 4 4 4 4
64 HR 1 4 2 4 LSM   -0.8561 -8.0816 -4.7396 -7.4476 -12.397 -12.407  
65 HR 1 4 2 5 LSM s.e.   3.50066 3.50066 3.50066 3.50066 3.5007 3.5007  
66 HR 1 4 2 6 LSM = 0 p-value   0.808 0.026* 0.183 0.039* <.001* <.001*  
67 HR 1 4 3 1 Mean Change from Vehicle   10.387 1.8443 2.8940 10.559 0.2448 4.1975 5.0209
68 HR 1 4 3 2 SD   5.3319 7.01487 4.68906 9.4706 6.68270 7.02022 NA
69 HR 1 4 3 3 N   4 4 4 4 4 4 4
70 HR 1 4 3 4 LSM   9.0299 0.4877 1.5374 9.2019 -1.1118 2.8409  
71 HR 1 4 3 5 LSM s.e.   3.58641 3.58641 3.58641 3.58641 3.58641 3.58641  
72 HR 1 4 3 6 LSM = 0 p-value   0.015* 0.892 0.670 0.014* 0.758 0.432  
In [65]:
proc format; 
	 invalue param (notsorted) "HR" = 1 "PP" = 2 "SAP"= 3 "DAP"= 4 "MAP"= 5; 
     invalue dayff "Day 1"=1  "Day 3"=1; 
run;

data reportdata;
  set reportfinal;
  trt=cats(trtn);
/*  dayn=input(day,dayff.); */
run;

proc sort ; by paramn paramcd phase trtn trt rownum rowlbl;run;

data reportdatapg;
  set reportdata;
  by paramn paramcd phase trtn trt rownum rowlbl;
  if first.phase then page+1;;
/*  if trt="100" then trt="INTN ";*/
run;




/*==============================================================================
  PURPOSE:
    Create TFL-style PROC REPORT tables by PARAMCD (HR, SAP, DAP, MAP, PP),
    split across 4 analysis phases (1–4) with different time windows per page,
    and add a footer line describing the covariance structure used.
==============================================================================*/

/*--- Global listing layout / print formatting options ---*/
options missing=' ' nodate nonumber nocenter orientation=landscape
        pagesize=46 linesize=133
        formchar='|_---|+|---+=|-/\<>*';

/*--- Standard footnotes for all tables ---*/
footnote1 "-----------------------------------------------------------------------------------------------------------------------------------";
footnote2 "* : Statistically significant at the 0.05 level.                                                                                   ";
footnote3 "LSM = 0 p-value : Within dose level comparison with study day 1 vehicle.                                                           ";

/*--- Table titles (one per endpoint) ---*/
%let title1 = "Table 3.1: Analysis Summary Table for Change from Vehicle: Heart Rate";
/*%let title2 = "Table 3.2: Analysis Summary Table for Change from Vehicle: Systolic Arterial Pressure";*/
%let title3 = "Table 3.3: Analysis Summary Table for Change from Vehicle: Diastolic Arterial Pressure";
%let title4 = "Table 3.4: Analysis Summary Table for Change from Vehicle: Mean Arterial Pressure";
%let title5 = "Table 3.5: Analysis Summary Table for Change from Vehicle: Pulse Pressure";

/*--- Footer macros: print covariance structure note after each page ---*/
%macro cs;   compute after page; line @1 ' '; line @1 'Analysis Covariance Structure: Compound Symmetric'; endcomp; %mend;
%macro csh;  compute after page; line @1 ' '; line @1 'Analysis Covariance Structure: Compound Symmetric Heterogeneous'; endcomp; %mend;
%macro ar;   compute after page; line @1 ' '; line @1 'Analysis Covariance Structure: Autoregressive Order 1'; endcomp; %mend;
%macro arh;  compute after page; line @1 ' '; line @1 'Analysis Covariance Structure: Autoregressive Heterogeneous Order 1'; endcomp; %mend;

/*--- Column definitions per “phase page” (baseline + hours 1–6, then 7–12, 13–18, 19–24) ---*/
%macro def1;
   define page   / noprint order;
   define trtn   / noprint order;
   define trt    / "Dose|Level" left width=6 order;
   define rowlbl / "Statistic" left width=30;
   define rownum / noprint order;
   define time_0 / display "Baseline" right width=9;
   define time_1 / display "1|hour"   right width=9;
   define time_2 / display "2|hour"   right width=9;
   define time_3 / display "3|hour"   right width=9;
   define time_4 / display "4|hour"   right width=9;
   define time_5 / display "5|hour"   right width=9;
   define time_6 / display "6|hour"   right width=9;
   break after trtn / skip;
   break after page / page;
%mend;

%macro def2;
   define page   / noprint order;
   define trtn   / noprint order;
   define trt    / "Dose|Level" left width=6 order;
   define rowlbl / "Statistic" left width=30;
   define rownum / noprint order;
   define time_1 / display "7|hour"   right width=9;
   define time_2 / display "8|hour"   right width=9;
   define time_3 / display "9|hour"   right width=9;
   define time_4 / display "10|hour"  right width=9;
   define time_5 / display "11|hour"  right width=9;
   define time_6 / display "12|hour"  right width=9;
   break after trtn / skip;
   break after page / page;
%mend;

%macro def3;
   define page   / noprint order;
   define trtn   / noprint order;
   define trt    / "Dose|Level" left width=6 order;
   define rowlbl / "Statistic" left width=30;
   define rownum / noprint order;
   define time_1 / display "13|hour"  right width=9;
   define time_2 / display "14|hour"  right width=9;
   define time_3 / display "15|hour"  right width=9;
   define time_4 / display "16|hour"  right width=9;
   define time_5 / display "17|hour"  right width=9;
   define time_6 / display "18|hour"  right width=9;
   break after trtn / skip;
   break after page / page;
%mend;

%macro def4;
   define page   / noprint order;
   define trtn   / noprint order;
   define trt    / "Dose|Level" left width=6 order;
   define rowlbl / "Statistic" left width=30;
   define rownum / noprint order;
   define time_1 / display "19|hour"  right width=9;
   define time_2 / display "20|hour"  right width=9;
   define time_3 / display "21|hour"  right width=9;
   define time_4 / display "22|hour"  right width=9;
   define time_5 / display "23|hour"  right width=9;
   define time_6 / display "24|hour"  right width=9;
   break after trtn / skip;
   break after page / page;
%mend;

/*--- Reporting macros:
      Each macro prints 4 PROC REPORTs (phase=1..4), changing the hour window and covariance note. ---*/
%macro report1(paramcd=, title=);
  title1 &title;

  /* Phase 1: Baseline + hours 1–6 */
  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl time_0
           ('[--------------------------Analysis Phase 1-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=1;
    %def1
    %arh
  run;

  /* Phase 2: hours 7–12 */
  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 2-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=2;
    %def2
    %arh
  run;

  /* Phase 3: hours 13–18 */
  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 3-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=3;
    %def3
    %cs
  run;

  /* Phase 4: hours 19–24 */
  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 4-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=4;
    %def4
    %ar
  run;
%mend;

%macro report2(paramcd=, title=);
  title &title;
  /* All phases use CS note here */
  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl time_0
           ('[--------------------------Analysis Phase 1-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=1;
    %def1
    %cs
  run;

  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 2-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=2;
    %def2
    %cs
  run;

  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 3-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=3;
    %def3
    %cs
  run;

  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 4-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=4;
    %def4
    %cs
  run;
%mend;

%macro report3(paramcd=, title=);
  title &title;
  /* Same structure as report2; phase 1 header text slightly shorter */
  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl time_0
           ('[---------------------Analysis Phase 1--------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=1;
    %def1
    %cs
  run;

  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 2-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=2;
    %def2
    %cs
  run;

  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 3-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=3;
    %def3
    %cs
  run;

  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 4-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=4;
    %def4
    %cs
  run;
%mend;

%macro report4(paramcd=, title=);
  title &title;
  /* All phases use CS note here */
  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl time_0
           ('[--------------------------Analysis Phase 1-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=1;
    %def1
    %cs
  run;

  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 2-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=2;
    %def2
    %cs
  run;

  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 3-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=3;
    %def3
    %cs
  run;

  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 4-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=4;
    %def4
    %cs
  run;
%mend;

%macro report5(paramcd=, title=);
  title &title;
  /* Mixed covariance notes (ARH for phase 1; CS for phases 2–3; AR for phase 4) */
  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl time_0
           ('[--------------------------Analysis Phase 1-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=1;
    %def1
    %arh
  run;

  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 2-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=2;
    %def2
    %cs
  run;

  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 3-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=3;
    %def3
    %cs
  run;

  proc report data=reportdatapg nowd nowindows headskip split='|' missing spacing=1;
    columns page trtn trt trtn rownum rowlbl
           ('[--------------------------Analysis Phase 4-------------------------]' time_1-time_6);
    where paramcd=&paramcd and phase=4;
    %def4
    %ar
  run;
%mend;

/*--- Route LISTING output to an external .lst file ---*/
proc printto new print="&path.\SAS\OUTPUT\COR1043_tables_&SYSDATE9..lst";

/*--- Generate each table by endpoint ---*/
%report1(paramcd='HR',  title=&title1);
%report2(paramcd='SAP', title=&title2);
%report3(paramcd='DAP', title=&title3);
%report4(paramcd='MAP', title=&title4);
%report5(paramcd='PP',  title=&title5);

/*--- Clear titles/footnotes and restore default output destination ---*/
title;
footnote;
proc printto new print=print;
run;
SAS Output

Table 3.1: Analysis Summary Table for Change from Vehicle: Heart Rate

  [--------------------------Analysis Phase 1-------------------------]
Dose
Level
Statistic Baseline 1
hour
2
hour
3
hour
4
hour
5
hour
6
hour
1 Mean Change from Vehicle -5.6808 32.887 65.620 62.210 62.277 50.920 51.484
  SD 5.35020 26.4502 22.4734 14.2521 10.7755 18.2817 12.4820
  N 4 4 4 4 4 4 4
  LSM -5.6808 33.494 66.227 62.817 62.885 51.528 52.091
  LSM s.e. 3.53068 9.4020 8.6803 6.5935 6.3018 7.3207 4.3766
  LSM = 0 p-value 0.142 <.001* <.001* <.001* <.001* <.001* <.001*
2 Mean Change from Vehicle 0.4820 2.8933 30.080 28.284 21.067 21.256 15.926
  SD 8.79171 18.32200 16.4893 13.7110 13.1081 7.0977 3.4467
  N 4 4 4 4 4 4 4
  LSM 0.4820 2.7469 29.933 28.137 20.920 21.109 15.779
  LSM s.e. 3.53068 9.29278 8.5619 6.4368 6.1377 7.1799 4.1368
  LSM = 0 p-value 0.894 0.769 0.001* <.001* 0.001* 0.005* <.001*
3 Mean Change from Vehicle 3.0553 -10.479 24.696 23.208 22.907 29.218 20.813
  SD 6.60833 12.5510 16.7581 14.0077 13.3197 12.5136 2.3645
  N 4 4 4 4 4 4 4
  LSM 3.0553 -10.940 24.235 22.747 22.446 28.757 20.351
  LSM s.e. 3.53068 9.3530 8.6273 6.5235 6.2285 7.2577 4.2704
  LSM = 0 p-value 0.409 0.248 0.007* 0.001* <.001* <.001* <.001*
 
Analysis Covariance Structure: Autoregressive Heterogeneous Order 1

-----------------------------------------------------------------------------------------------------------------------------------

* : Statistically significant at the 0.05 level.

LSM = 0 p-value : Within dose level comparison with study day 1 vehicle.


Table 3.1: Analysis Summary Table for Change from Vehicle: Heart Rate

  [--------------------------Analysis Phase 2-------------------------]
Dose
Level
Statistic 7
hour
8
hour
9
hour
10
hour
11
hour
12
hour
1 Mean Change from Vehicle 21.215 40.394 45.012 28.181 39.603 32.725
  SD 13.3448 11.3117 8.6502 15.2532 16.0131 13.4334
  N 4 4 4 4 4 4
  LSM 25.729 44.907 49.526 32.695 44.116 37.238
  LSM s.e. 6.0514 3.7927 2.9337 7.5557 5.8270 5.3551
  LSM = 0 p-value <.001* <.001* <.001* <.001* <.001* <.001*
2 Mean Change from Vehicle 1.8203 12.587 15.388 15.828 20.142 6.5480
  SD 9.84040 5.4118 7.9559 8.1258 4.0932 6.66645
  N 4 4 4 4 4 4
  LSM 0.7328 11.499 14.300 14.740 19.054 5.4605
  LSM s.e. 5.93683 3.6072 2.6896 7.4643 5.7080 5.22531
  LSM = 0 p-value 0.902 0.003* <.001* 0.054 0.002* 0.302
3 Mean Change from Vehicle 1.7793 17.523 12.252 25.109 29.862 29.819
  SD 11.12709 8.5156 5.7771 12.6284 9.3523 9.2791
  N 4 4 4 4 4 4
  LSM -1.6469 14.097 8.8256 21.683 26.436 26.392
  LSM s.e. 6.00010 3.7104 2.82648 7.5147 5.7738 5.2971
  LSM = 0 p-value 0.785 <.001* 0.003* 0.006* <.001* <.001*
 
Analysis Covariance Structure: Autoregressive Heterogeneous Order 1

-----------------------------------------------------------------------------------------------------------------------------------

* : Statistically significant at the 0.05 level.

LSM = 0 p-value : Within dose level comparison with study day 1 vehicle.


Table 3.1: Analysis Summary Table for Change from Vehicle: Heart Rate

  [--------------------------Analysis Phase 3-------------------------]
Dose
Level
Statistic 13
hour
14
hour
15
hour
16
hour
17
hour
18
hour
1 Mean Change from Vehicle 27.859 27.505 23.308 24.550 20.126 19.665
  SD 8.6534 6.6541 6.2420 9.5938 11.1809 6.0945
  N 4 4 4 4 4 4
  LSM 29.810 29.456 25.258 26.500 22.076 21.615
  LSM s.e. 3.4445 3.4445 3.4445 3.4445 3.4445 3.4445
  LSM = 0 p-value <.001* <.001* <.001* <.001* <.001* <.001*
2 Mean Change from Vehicle 9.3565 -1.9355 1.7350 0.4398 -2.4290 -1.0460
  SD 7.65104 8.17044 4.23825 10.18202 3.74822 2.86982
  N 4 4 4 4 4 4
  LSM 8.8866 -2.4054 1.2651 -0.0301 -2.8989 -1.5159
  LSM s.e. 3.31740 3.31740 3.31740 3.31740 3.31740 3.31740
  LSM = 0 p-value 0.010* 0.472 0.705 0.993 0.387 0.650
3 Mean Change from Vehicle 21.028 16.797 13.002 3.8520 7.8570 12.371
  SD 7.9806 4.4917 6.5361 4.56616 3.95595 7.0126
  N 4 4 4 4 4 4
  LSM 19.547 15.316 11.522 2.3715 6.3765 10.890
  LSM s.e. 3.3879 3.3879 3.3879 3.38788 3.38788 3.3879
  LSM = 0 p-value <.001* <.001* 0.001* 0.488 0.066 0.002*
 
Analysis Covariance Structure: Compound Symmetric

-----------------------------------------------------------------------------------------------------------------------------------

* : Statistically significant at the 0.05 level.

LSM = 0 p-value : Within dose level comparison with study day 1 vehicle.


Table 3.1: Analysis Summary Table for Change from Vehicle: Heart Rate

  [--------------------------Analysis Phase 4-------------------------]
Dose
Level
Statistic 19
hour
20
hour
21
hour
22
hour
23
hour
24
hour
1 Mean Change from Vehicle 20.720 16.689 18.946 13.566 7.0670 -2.5748
  SD 4.6006 6.4045 7.8181 9.8952 9.91546 11.55177
  N 4 4 4 4 4 4
  LSM 22.507 18.476 20.733 15.353 8.8541 -0.7876
  LSM s.e. 3.6550 3.6550 3.6550 3.6550 3.65504 3.65504
  LSM = 0 p-value <.001* <.001* <.001* <.001* 0.020* 0.830
2 Mean Change from Vehicle -0.4255 -7.6510 -4.3090 -7.0170 -11.966 -11.977
  SD 6.44556 7.24202 5.87769 4.53746 7.5879 5.5382
  N 4 4 4 4 4 4
  LSM -0.8561 -8.0816 -4.7396 -7.4476 -12.397 -12.407
  LSM s.e. 3.50066 3.50066 3.50066 3.50066 3.5007 3.5007
  LSM = 0 p-value 0.808 0.026* 0.183 0.039* <.001* <.001*
3 Mean Change from Vehicle 10.387 1.8443 2.8940 10.559 0.2448 4.1975
  SD 5.3319 7.01487 4.68906 9.4706 6.68270 7.02022
  N 4 4 4 4 4 4
  LSM 9.0299 0.4877 1.5374 9.2019 -1.1118 2.8409
  LSM s.e. 3.58641 3.58641 3.58641 3.58641 3.58641 3.58641
  LSM = 0 p-value 0.015* 0.892 0.670 0.014* 0.758 0.432
 
Analysis Covariance Structure: Autoregressive Order 1

-----------------------------------------------------------------------------------------------------------------------------------

* : Statistically significant at the 0.05 level.

LSM = 0 p-value : Within dose level comparison with study day 1 vehicle.

In [ ]: