option ps=500 ls=80 nodate nonumber;
/*
This program determines the total required sample size given
f = the fraction allocated to Treatment
alpha = type I error probability
beta = type II error probability
sides = number of sides to the test of hypothesis
delta = treatment effect
sigma = between-patient standard deviation
tau = between-site variance or gamma and omega
s = number of different subgroups (sizes) of sites
m1, m2, etc = numbers of sites in each subgroup. In the first subgroup each site has the least number of patients
r1, r2, etc = ratios site sizes; i.e. r1 = n2/n1, r1 = 1; ri > 1
*/
%macro GivenTau;
proc iml;
n = j(&s,1,0);
mTotal = 0;
do k = 1 to &s;
mTotal = mTotal + &m[k];
end;
tau = &tau_input;
a = 1/(&f*(1 - &f));
sigmaSQD = &sigma**2;
deltaSQD = &delta**2;
tAlpha = tinv(1 - &alpha/&sides,mTotal - 1);
tBeta = tinv(1 - &beta,mTotal - 1);
capA = (tAlpha + tBeta)**2;
nTotalNaive = round(( a*capA*sigmaSQD/deltaSQD),1 );
print "Total number of patients required ignoring site effect:" nTotalNaive;
if mTotal < tau*capA/(&delta**2) then print "No solution, more sites required.";
if mTotal >= tau*capA/(&delta**2) then do; * Start of Loop 1;
inflationFactor1 = (mTotal*deltaSQD)/(mTotal*deltaSQD - capA*tau);
nTotalSame = round(nTotalNaive*inflationFactor1,1);
print "Total number of patients required if all sites were the same size:" nTotalSame;
print "Inflation factor for equal site sizes" inflationFactor1;
vGoal = deltaSQD/capA;
vActual = vGoal + 1;
n[1] = 0;
do until (vActual < vGoal | n[1] > 1000000); * Start of Loop 2;
n[1] = n[1] + 2;
do k = 1 to &s;
n[k] = n[1]*&r[k];
end;
vInverse = 0;
do k = 1 to &s;
vInverse = vInverse + ( (&m[k]*n[k]) / ((a*sigmaSQD) + (n[k]*tau)) );
end;
vActual = 1/vInverse;
end; * End of Loop 2;
if n[1] >= 1000000 then print "No solution, more than 1,000,000 patients/site needed. More sites required.";
if n[1] < 1000000 then do; * Start of Loop 3;
do k = 2 to &s;
n[k] = round(n[k],1);
end;
nTotal = 0;
do k = 1 to &s;
nTotal = nTotal + &m[k]*n[k];
end;
print "Total number of patients required (n) for each site, ordered by subgroup:" n;
print "Total number of patients required across all sites:" nTotal;
inflationFactor2 = nTotal/nTotalNaive;
print "Inflation factor for UNequal site sizes" inflationFactor2;
end; * End of Loop 3;
end; * End of Loop 1;
quit;
%mend;
%macro GivenGammaOmega;
proc iml;
n = j(&s,1,0);
mTotal = 0;
do k = 1 to &s;
mTotal = mTotal + &m[k];
end;
zOmega = probit((1 + &omega)/2);
tau = ( &gamma*&delta/zOmega )**2;
print tau;
a = 1/(&f*(1 - &f));
sigmaSQD = &sigma**2;
deltaSQD = &delta**2;
tAlpha = tinv(1 - &alpha/&sides,mTotal - 1);
tBeta = tinv(1 - &beta,mTotal - 1);
capA = (tAlpha + tBeta)**2;
nTotalNaive = round(( a*capA*sigmaSQD/deltaSQD),1 );
print "Total number of patients required ignoring site effect:" nTotalNaive;
if mTotal < tau*capA/(&delta**2) then print "No solution, more sites required.";
if mTotal >= tau*capA/(&delta**2) then do; * Start of Loop 1;
inflationFactor1 = (mTotal*deltaSQD)/(mTotal*deltaSQD - capA*tau);
nTotalSame = round(nTotalNaive*inflationFactor1,1);
print "Total number of patients required if all sites were the same size:" nTotalSame;
print "Inflation factor for equal site sizes" inflationFactor1;
vGoal = deltaSQD/capA;
vActual = vGoal + 1;
n[1] = 0;
do until (vActual < vGoal | n[1] > 1000000); * Start of Loop 2;
n[1] = n[1] + 2;
do k = 1 to &s;
n[k] = n[1]*&r[k];
end;
vInverse = 0;
do k = 1 to &s;
vInverse = vInverse + ( (&m[k]*n[k]) / ((a*sigmaSQD) + (n[k]*tau)) );
end;
vActual = 1/vInverse;
end; * End of Loop 2;
if n[1] >= 1000000 then print "No solution, more than 1,000,000 patients/site needed. More sites required.";
if n[1] < 1000000 then do; * Start of Loop 3;
do k = 2 to &s;
n[k] = round(n[k],1);
end;
nTotal = 0;
do k = 1 to &s;
nTotal = nTotal + &m[k]*n[k];
end;
print "Total number of patients required (n) for each site, ordered by subgroup:" n;
print "Total number of patients required across all sites:" nTotal;
inflationFactor2 = nTotal/nTotalNaive;
print "Inflation factor for UNequal site sizes" inflationFactor2;
end; * End of Loop 3;
end; * End of Loop 1;
quit;
%mend;
%let f = 0.5; * the fraction allocated to Treatment;
%let delta = 0.2; * treatment effect {= delta(Optimal Design)*sigma};
%let sigma = 1; * between-patient standard deviation;
%let alpha = 0.05; * type I error probability;
%let beta = 0.2; * type II error probability;
%let sides = 2; * number of sides to the test of hypothesis;
%let method = 'gamma'; * for method = 'tau', provide value of tau_Input, for method 'gamma' provide values of gamma and omega;
%let s = 3; * number of different subgroups (sizes) of sites;
%let m = %str( {4,4,4} ); * the number of sites in each subgroup, the first value is the number of the smallest sites.
s values required.
if m = %str( {12,8,5} ), then there are 12 sites in the subgroup of the smallest sites,
8 sites in the second subgroup, and 5 sites in the third subgroup.;
%let r = %str( {1,5,10} ); * the relative number of patients/site for each subgroup compared to the smallest sites (subgroup 1),
where r[i] = n[i]/n[1], where n[i] is the total number of patients/site in the ith subgroup and n[1] is the number
of patients from each of the smallest sites (subgroup 1).
s values required (r[1] = 1)
if r = %str( {1,4,2}) then there 5 times as many patients/site in the second subgroup, compared to the smallest sites,
and 5 times as many patients/site in the third subgroup, compared to the smallest sites;
%let tau_Input = 0.0003023; * between-site variance;
%GivenTau;
%let gamma = 0.1;
%let omega = 0.75;
%GivenGammaOmega;