*Appendix 2

advertisement
*Appendix 2;
*SAS code for analyses in Mascha EJ, Sessler DI, "Equivalence and noninferiority testing in
regression models and repeated measures designs", Anesthesia & Analgesia, 2011;112:678-87.
* Dataset is available in online Appendix 1 with permission from authors of Ruetzler et al;
* Correspondence to Edward J. Mascha, PhD, Cleveland Clinic Department of Quantitative Health
Sciences, maschae@ccf.org;
options nodate nonumber nocenter sortpgm=best formdlim='~';
proc format;
value sleeve
value
0 = "Forced Air"
1 = "Warm-water sleeve";
site
1 = "CCF"
2 = "Vienna";
run;
*NAME YOUR DIRECTORY;
%let dir= YOUR DIRECTORY containing ruetzler_et_al.xls;
%let data=ruetzler_et_al.xls;
proc import datafile="&dir\&data" out=work.ruetzler_rm replace;
proc print data= ruetzler_rm (obs=10);
format site_id site. sleeve sleeve.; format esophtemp preop_temp 5.1;
run;
proc contents data=ruetzler_rm position; run;
proc freq data= ruetzler_rm;
table time_m site_id;run;
*Create dataset for analysis at single time point, 60 minutes (Section 2 manuscript);
data temp60; set ruetzler_rm;
if time_m = 60;
temp60=esophtemp;
run;
title 'Section 2.1 t-test for superiority';
proc ttest data=temp60; class sleeve; var temp60;run;
*Section 2. Basic testing;
*Estimate means and standard deviations within group;
proc means data=temp60 mean stddev;* noprint;
var temp60; class sleeve;
output out= summary_60 mean= m stddev= s n=n; run;
*Merge group 0 and 1 summary statistics into single row;
data m1 m2; set summary_60;
if sleeve=1 then do;
m1= m;
s1=s; n1=n; d=1;
output m1;
end;
if sleeve=0 then do;
m2= m;
s2=s; n2=n; d=1;
output m2;
end; run;
data merge12 (keep=diff n1 n2 m1 m2 s1 s2 sd_p var_p se t_sup tcrit_sup pv_sup delta
t_ni pv_noninf tcrit_ni);
update m1 m2; by d;
diff=m1-m2;
var_p= ((n1-1)*s1**2 + (n2-1)*s2**2)/ (n1 + n2 -2);
*pooled SD;
sd_p= sqrt(var_p);
*pooled variance;
se= sqrt(var_p*(1/n1 + 1/n2)); *SD of difference in means = standard error;
*Superiority test: equations (2) and (3);
alpha_s=.05;
t_sup= diff/ se;
tcrit_sup = TINV(1-alpha_s/2,n1+n2-2); *critical value for superiority at alpha=0.05
(2-sided test);
pv_sup= 2*(1-probt(abs(t_sup),n1+n2-2)); *p-value for superiority;
*Noninferiority test: equations (6) and (7);
alpha_ni=.025;
delta= 0.5; *degrees Celsius;
t_ni= (diff+delta)/ se;
tcrit_ni = TINV(1- alpha_ni,n1+n2-2);
*critical value for NI at alpha=0.025(1-sided);
pv_noninf= (1-probt(abs(t_ni),n1+n2-2));
run;
title "Sections 2.1, 2.3: 'by-hand' superiority and noninferiority testing with single
observation per subject";
proc print data= merge12; run;
title1 '3.1. Testing for superiority of sleeve to forced air at 60 minutes in linear
regression model';
proc glm data = temp60;
model temp60 = sleeve /solution; *This is equation (9), and tests HO: beta=0 as in (10);
ods output
ParameterEstimates = beta60; run;
*proc print data=beta60;run;
title1 '3.2: Testing for noninferiority (and equivalence) of warm water sleeve to forced air
at 60 minutes';
title2 'using regression model output';
title 'Noninferiority delta = 0.5 degrees Censius';
data beta60; set beta60;
if parameter='sleeve';
n1=37; n2=34; *sample sizes
df= n1+n2-2;
beta1 = estimate;
* beta1 =
=
Se_diff = stderr; *SE_beta1=
for VH and FA;
estimated treatment effect
estimated mean VH - mean FA if no additional covariables;
SE of estimated treatment effect beta1;
*2-tailed test for superiority;
*GLM output: P-value for 2-sided test for superiority,
pvalue_sup = probt;
HO: beta= mean VH - mean FA=0;
*Manuscript Equation 11;
*hand-calculate test for superiority using estimated treatment effect and standard error;
t_sup= (beta1)/se_diff;
pval_sup= 2*(1- (probt(ABS(t_sup),df))); *alpha =0.05, reject Null if P-value < 0.05;
*95% confidence interval for treatment effect (sleeve minus forced air);
Z_sup95 = abs(probit(.05/2));
*1.96; *split alpha using half on each side;
lower_CL = beta1 - 1.96 * se_diff;
upper_CL = beta1 + 1.96 * se_diff;
*NONINFERIORITY testing at 60 minutes;
* A. HIGHER VALUES OF OUTCOME DESIRABLE;
*HO: beta1 = mean SLEEVE - mean FA <= -0.5;
*H1: beta1 = mean SLEEVE - mean FA > -.5;
*DELTA =0.5;
*Manuscript Equation 12;
*test non-inf: beta1 + .5 > 0; *NOTE: 'less than' sign and '+' agree with H1 above;
t_noninf_a= (beta1 + .5)/se_diff;
pval_noninf_a= 1-probt(t_noninf_a,df);
*P-value= 1 minus Prob(T < t_noninf): 1-sided test;
*with alpha of 0.025 (or 0.05), reject null and claim noininferiority
if P < 0.025 (or 0.05);
* B. LOWER VALUES OF OUTCOME DESIRABLE;
*HO: beta1= mean SLEEVE - mean FA >= 0.5;
*H1: beta1= mean SLEEVE - mean FA < 0.5;
*DELTA =0.5;
*test non-inf: beta1 - .5 > 0; *'greater than' sign and '-' agree with H1 above;
t_noninf_b= (beta1 - .5)/se_diff;
pval_noninf_b= probt(t_noninf_b,df); *P-value= P (T < t_noninf): 1-sided test;
*EQUIVALENCE TESTING at 60 minutes;
*TWO 1-SIDED TESTS USING DELTA OF 0.5 DEGREES CELSIUS;
*1. Conclude equivalence at delta of 0.5 degrees if beta_diff is significantly
above -delta and significantly below +delta; *If equivalence alpha is 0.05, would
use criterion of P<0.05 for each of the lower and upper boundary tests;
*Two 1-sided tests for equivalence are identical to the two noninferiority
tests above -- A. tests the lower boundary, B. tests upper boundary;
*2. Confidence interval for equivalence is at the 1 minus (2 X alpha) level;
*if alpha=0.05 for equivalence testing, will have 90% CI (0.05 on each side);
Z_equiv05 = abs(probit(.05));
*Z-equiv is 1.645 for alpha=0.05;
lower_90CI_equiv05 = beta1 - Z_equiv05 * se_diff;
upper_90CI_equiv05 = beta1 + z_equiv05 * se_diff;
run;
title1 '3.2: Testing for noninferiority (and equivalence) of warm water sleeve to forced air
at 60 minutes';
title2 'using regression model output';
title 'Noninferiority delta = 0.5 degrees Censius';
proc print data=beta60;
run;
*REPEATED MEASURES MODELS;
*chosen within-subject correlation structure is compound symmetry, specified with type=cs
in repeated statement below;
*alternatively, fit a spatial structure such as type= SP(POW)(time_M) to model correlation
fading as distance increases;
*fitting autoregressive structure [using type=AR(1)] not appropriate unless all
measurements equi-distant;
*1. TEST GROUP and TIME effects, assuming no interaction;
title "RM1 (3.3.2) Group and Time effects, no interaction model: time as categorical
variable";
proc mixed data = ruetzler_rm;
class pt_id time_m sleeve;
model esophtemp = sleeve time_m/solution ;
repeated /subject =pt_id type= cs ;
run;
*2a. Assess the GROUP-TIME INTERACTION: time as a categorical variable;
title 'RM2a (3.3.2) Assessing the GROUP-TIME INTERACTION: Time categorical (Equation 15)';
proc mixed data = ruetzler_rm order = internal;
class pt_id time_m sleeve;
model esophtemp = sleeve time_m sleeve*time_m /solution ;
repeated /subject =pt_id type= cs ;
lsmeans sleeve*time_m/ pdiff; *Can obtain treatment effect at each time by searching
through output; run;
*2b. Assess the GROUP-TIME INTERACTION with time as continuous variable;
title 'RM2b (3.3.2) Assessing the GROUP-TIME INTERACTION: Time continuous (Equation 14)';
proc mixed data = ruetzler_rm order = internal;
class pt_id sleeve; *remove 'time_m' from the class statement -- makes time continuous;
model esophtemp = sleeve time_m sleeve*time_m /solution ;
repeated /subject =pt_id type= cs ;
run;
*3. Assessing TREATMENT EFFECT AT EACH TIME, given the treatment-by-time interaction;
title "RM3 (3.3.2) Time categorical, test TX effect at each time in linear mixed model";
title2 "(Equation 16): remove intercept & group main effect so interaction effects estimate TX
effect at each time";
proc mixed data = ruetzler_rm ;
where esophtemp ne .;
class pt_id time_m site_id;
*Do not include 'group' variable in class statement for this model;
model esophtemp = time_m
sleeve*time_m/solution noint; *Group main effect removed;
repeated /subject =pt_id type= cs rcorr;
ods output SolutionF =solutionf;
run;
*4. Assessing noninferiority in linear mixed effects model;
data rma; set solutionf; *set parameter estimates and standard errors from linear mixed
model in 3 above;
where effect ='sleeve*time_m' and time_m in(60,120,180,240);
n1=37; n2=34; *sample sizes for Sleeve and FA;
df= n1+n2-2;
beta1=estimate; *treatment effect estimate at specific time-- column 4 of Table 1;
se_diff = stderr; *treatment effect standard error (adjusting for within-subject
correlation);
*test non-inf: H1: beta1 + .5 > 0; *H1 as in A. above -- higher values desirable;
t_noninf_lme= (beta1 + .5)/se_diff; *as Manuscript Equation 11;
*calculate noninferiority P-values at each hour;
pval_noninf_lme= 1-probt(t_noninf_lme,df);
*P-value= 1 minus P (T < t_noninf): 1-sided test;
*calculate lower confidence limit at each hour using alpha of 0.025;
Z_NI_025 = abs(probit(.025));
*Z_NI_025 is 1.96 for alpha=0.025;
*Results for confidence intervals reported in Table 1 of this article;
lower_95CI_lme = beta1 - Z_NI_025 * se_diff; *Lower limit is relevant for this NI test…;
*since higher values of temperature are desirable;
upper_95CI_lme = beta1 + Z_NI_025 * se_diff; *upper (opposite) limit often reported
for informational purposes;
run;
*Title 'RM4 (3.3.2) Noninferiority in linear mixed effects model';
proc print;
run;
Download