*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;