*****************************************************************************;
*                                                                           *;
*   HAYSPOWEM.SAS:  Hays' power macro written in SAS.                       *;
*								                              *;
*   Original program written in BASIC by Ron Hays, 1996.                    *;
*   see:                                                                    *;
*   https://drhays.dgsom.ucla.edu/pages/programs_utilities (hayspowe.bas)   *;
*                                 				                         *;
*                                 				                         *;
*   This program, HAYSPOWE.SAS, was written by Karen Spritzer               *;
*   for SAS 8.0, 3/22/2004.                                                 *;
*   Modified on 8/23/2004.                                                  *;	
*   Link to code is:                                                        *;
*   https://drhays.dgsom.ucla.edu/pages/programs_utilities (hayspowe.sas)   *;
*                                                                           *;
*   NOTES: do not alter code in the macro - only modify the macro call.     *;
*   The macro allows up to 10 scales and a sample call to the               *;
*   macro is at the bottom of the code.                                     *;
*   Note that in the program, scale names > 20 characters are truncated     *;
*   to 20 to keep table columns in line in the output.                      *;
*                                                                           *;
*****************************************************************************;

/*********** DO NOT MODIFY ANYTHING BETWEEN "%MACRO HAYSPOWEM" AND "&MEND HAYSPOWEM" ***********/

%MACRO HAYSPOWEM(
TITLE=,
sd1=,sd2=,sd3=,sd4=,sd5=,sd6=,sd7=,sd8=,sd9=,sd10=,
nscal1=,nscal2=,nscal3=,nscal4=,nscal5=,nscal6=,nscal7=,nscal8=,nscal9=,nscal10=,
nscales=,outfile=);

proc sql;
   create table temp
       (sd num,
        scale char(30));
 
  insert into temp
    values(&sd1, &nscal1)
    values(&sd2, &nscal2)
    values(&sd3, &nscal3)
    values(&sd4, &nscal4)
    values(&sd5, &nscal5)
    values(&sd6, &nscal6)
    values(&sd7, &nscal7)
    values(&sd8, &nscal8)
    values(&sd9, &nscal9)
    values(&sd10,&nscal10);

data temp; set temp;
scale=substr(scale,1,20);
if _N_ <= &nscales;
run;

/**** TABLE 1 ****/

data _null_; file "&outfile";

put &TITLE /
"                                                                     " /
"                                                                     " /
"Table 1: Sample sizes needed per group to detect differences           " /
"between two experimental groups, repeated measures design.           " /
"                                                                     " /
"                                               Number of Points Difference" /
"Scale Name              R      SD     VAR          2      5     10     20 " /
"_________________________________________________________________________    ";
run;

data _null_; file "&outfile" mod; set temp;
r=.60;
rsquare=r*r;
var=sd*sd;

two   =15.68*var*(1-rsquare)/  4;
five  =15.68*var*(1-rsquare)/ 25;
ten   =15.68*var*(1-rsquare)/100;
twenty=15.68*var*(1-rsquare)/400;

put scale +1 @23 r 4.2 @30 sd 5.2 @37 var 7.2 @46 two 7.0 @53 five 7.0 @60 ten 7.0 @67 twenty 7.0;

run;

data _null_; file "&outfile" mod; 

put //
"_______________________________________________________________    " /
"                                                                     " /
"Note: Estimates assume alpha = 0.05, two-tailed t-test, power = 80%, " /
"and an intertemporal correlation between scores of 0.60.             " /
"                                                                     " /
"                                                                     " /;

/**** TABLE 2 ****/

data _null_; file "&outfile" mod;

put &TITLE /
"                                                                     " /
"                                                                     " /
"Table 2: Sample sizes needed per group to detect differences           " /
"between two experimental groups, post-intervention measures only.     " /
"                                                                     " /
"                                               Number of Points Difference" /
"Scale Name                     SD     VAR          2      5     10     20 " /
"_________________________________________________________________________    ";
run;

data _null_; file "&outfile" mod; set temp;
r=.60;
rsquare=r*r;
var=sd*sd;

two2   =15.68*var/  4;
five2  =15.68*var/ 25;
ten2   =15.68*var/100;
twenty2=15.68*var/400;

put scale +1           @30 sd 5.2 @37 var 7.2 @46 two2 7.0 @53 five2 7.0 @60 ten2 7.0 @67 twenty2 7.0;

run;

data _null_; file "&outfile" mod; 

put //
"_______________________________________________________________    " /
"                                                                     " /
"Note: Estimates assume alpha = 0.05, two-tailed t-test, and power = 80%.  "/
"                                                                     " /;

/**** TABLE 3 ****/

data _null_; file "&outfile" mod;

put  &TITLE /
"                                                                     " /
"                                                                     " /
"Table 3: Sample sizes needed per group to detect differences           " /
"between two self-selected groups, repeated measures design.     " /
"                                                                     " /
"                                               Number of Points Difference" /
"Scale Name              R      SD     VAR          2      5     10     20 " /
"_________________________________________________________________________    ";
run;

data _null_; file "&outfile" mod; set temp;
r=.60;
rsquare=r*r;
var=sd*sd;

two3   =15.68*var*2*(1-r)/  4;
five3  =15.68*var*2*(1-r)/ 25;
ten3   =15.68*var*2*(1-r)/100;
twenty3=15.68*var*2*(1-r)/400;

put scale +1 @23 r 4.2 @30 sd 5.2 @37 var 7.2 @46 two3 7.0 @53 five3 7.0 @60 ten3 7.0 @67 twenty3 7.0;

run;

data _null_; file "&outfile" mod; 

put //
"_______________________________________________________________    " /
"                                                                     " /
"Estimates assume alpha = 0.05, two-tailed t-test, power = 80%,   " /
"and an intertemporal correlation between scores of 0.60.                    " /
"                                                                     " /
"                                                                     " /;
run;

/*********** END OF "MACRO" ***********/

%MEND HAYSPOWEM;

** Here's the macro call;
** it wants the TITLE, 
   # of scales to expect, 
   the SD/Name for each scale, and 
   the file to write the results to;

/** example **/

%hayspowem(
TITLE="Power call for RCMAR study",
nscales=3,
sd1=20.10,nscal1="PHYSICAL FUNCTIONING",
sd2=5.4  ,nscal2="EMOTIONAL WELL-BEING is a very long title",
sd3=30   ,nscal3="SOCIAL FUNCTIONING",
sd4=4    ,nscal4="scale4",
sd5=5    ,nscal5="scale5",
sd6=6    ,nscal6="scale6",
sd7=7    ,nscal7="scale7",
sd8=8    ,nscal8="scale8",
sd9=9    ,nscal9="scale9",
sd10=10  ,nscal10="scale10",
outfile=hayspowe.out);