*! version 1.0 capture program drop dunnett program define dunnett, rclass syntax varlist(min=2 max=2) [if] [in] , CONtrol(real) /* */ [ci(integer 95) Side(integer 2) NOlabel SEParator(integer 5) MIssing] gettoken resp fact: varlist /* Mark sample for computations */ /* If missing is specified, treat missing as category */ if "`missing'" == ""{ marksample touse qui count if `touse' } else{ marksample touse, novarlist qui count if `touse' } /* Make sure we do not have zero observations in sample */ if r(N)==0 { error 2000 } /* Check assumptions */ /* Check that separator() is positive */ if `separator' <0 { di in red "separator() incorrectly specified" exit 198 } /* Check that ci() option is only 95 or 99 */ if `ci' != 95 & `ci' != 99{ di in red "ci() must be 95 or 99" exit 198 } /* Check that side() option is only 1 or 2 */ if `side' != 1 & `side' != 2{ di in red "side() must be 1 or 2" exit 198 } /* Check that number of treatments are less than 22 for 2 sided interval */ qui levelsof `fact' if `touse', local(levels) missing local k: word count `levels' /* k is total number of treatments including control */ if `k' >21 & `side'==2{ di in red "two sided intervals must have 21 or less treatments including control" exit 198 } /* Check that number of treatments are less than 11 for 1 sided interval */ if `k' >10 & `side'==1{ di in red "one sided intervals must have 10 or less treatments including control" exit 198 } /* Make sure control() is in factor_var */ local infact = 0 foreach factor of local levels{ if `factor' == `control'{ local infact = 1 } } if `infact' == 0{ di in red "control = `control' is not in `fact'" exit 198 } /* Check that sample size is the same for all groups */ qui count if `fact' == `control' & `touse' local n = r(N) foreach i of local levels{ qui count if `fact' == `i' & `touse' if r(N) != `n'{ di in red "sample sizes of each group must be equal" exit 198 } } /* Count observations in sample */ qui count if `touse' local N = r(N) /* Call oneway and save mse and df */ qui oneway `resp' `fact' if `touse',missing local mse = r(rss)/r(df_r) local df = r(df_r) /* Make sure df is at least 5 */ if `df' < 5{ di in red "degrees of freedom must be at least five" exit 198 } /* Call program d_table for table value and store in d */ d_table `side' `ci' `df' `k' local d = `r(d)' /* Calculate Dunnett criterion value */ local criterion = `d' * sqrt(2*`mse'/(`n')) /* Create local list of treatments excluding control */ local list : list levels - control /* If option nolabel is not specified */ if "`nolabel'" == ""{ /* extract value labels if labels exist */ local factorlab: value label `fact' if "`factorlab'" != ""{ local lab`control': label `factorlab' `control' if `"`lab`control''"' == ""{ local lab`control' = `control' } foreach group of local list{ if "`group'" == "."{ local labmiss = . } else{ local lab`group': label `factorlab' `group' if `"`lab`group''"' == ""{ local lab`group' = `group' } } } } /* if factor_var does not have labels */ if "`factorlab'" == ""{ local lab`control' = `control' foreach group of local list{ if "`group'" == "."{ local labmiss = . } else{ local lab`group' = `group' } } } } /* if option nolabel is specified */ if "`nolabel'" != ""{ local lab`control' = `control' foreach group of local list{ if "`group'" == "."{ local labmiss = . } else{ local lab`group' = `group' } } } /* calculate control mean */ qui sum `resp' if `fact'==`control' & `touse', meanonly local control_mean = r(mean) /* Calculations and table output for 2 sided intervals */ if `side' == 2{ /* Calculate differences and confidence interval */ foreach group of local list{ if "`group'" == "."{ local g = "miss" } else{ local g = `group' } qui sum `resp' if `fact'==`group' & `touse', meanonly local mean`g' = r(mean) local diff`g' = `mean`g'' - `control_mean' local abs_diff`g' = abs(`diff`g'') local lb`g' = `diff`g'' - `criterion' local ub`g' = `diff`g'' + `criterion' if `abs_diff`g'' > `criterion'{ local conclusion`g' "Yes" } else{ local conclusion`g' "No" } } /* Create table output */ /* Header */ #delimit ; di in smcl in gr "{hline 9}{c TT}{hline 74}"; di in smcl in gr _col(9) " {c |}" _col(74) "Different"; di in smcl in gr %8s abbrev("`fact'",8) " {c |}" _col(17) "Mean" _col(29) "Diff" _col(36) "[ 2-Sided `ci'% SCI ]" _col(60) "abs(Diff)" _col(72) "from Control?"; #delimit cr di in smcl in gr "{hline 9}{c +}{hline 74}" /* Output for control */ #delimit ; di in smcl in gr %8s abbrev("`lab`control'' ",8) " {c |}" in ye _col(12) %9.0g `control_mean' _col(30) "---" _col(42) "--- ---" _col(66) "---" _col(77) "---"; #delimit cr /* Output for all treatments excluding control */ local i = 0 foreach group of local list{ local i = `i' + 1 if mod(`i',`separator')==0{ di in smcl in gr "{hline 9}{c +}{hline 74}" } if "`group'" == "."{ local g = "miss" local shortlab = . } else{ local g = `group' local shortlab = abbrev("`lab`g''",8) } #delimit ; di in smcl in gr %8s "`shortlab'" " {c |}" in ye _col(12) %9.0g `mean`g'' _col(24) %9.0g `diff`g'' _col(36) %9.0g `lb`g'' " " %9.0g `ub`g'' _col(60) %9.0g `abs_diff`g'' _col(77) %3s "`conclusion`g''" ; #delimit cr } /* Bottom line and notes */ di in smcl in gr "{hline 9}{c BT}{hline 74}" local shortfact = abbrev("`fact'",8) di in smcl in gr _col(6) "Diff = mean(`shortfact')-mean(control)" di in smcl in gr _col(6) "Different from mean(control) if abs(Diff) > " %8.0g `criterion' } /* Calculations and table output for 1 sided interval */ if `side' == 1{ /* Calculate differences and lower and upper bounds */ foreach group of local list{ if "`group'" == "."{ local g = "miss" } else{ local g = `group' } qui sum `resp' if `fact'==`group' & `touse', meanonly local mean`g' = r(mean) local diff`g' = `mean`g'' - `control_mean' local lb`g' = `diff`g'' - `criterion' local ub`g' = `diff`g'' + `criterion' if `diff`g'' > `criterion'{ local greater`g' "Yes" } else{ local greater`g' "No" } if `diff`g'' < -`criterion'{ local less`g' "Yes" } else{ local less`g' "No" } } /* Header */ #delimit ; di in smcl in gr "{hline 9}{c TT}{hline 82}"; di in smcl in gr _col(9) " {c |}" _col(38) "`ci'% SCI" _col(52) "`ci'% SCI" _col(67) "Greater" _col(84) "Less"; di in smcl in gr %8s abbrev("`fact'",8) " {c |}" _col(17) "Mean" _col(29) "diff" _col(36) "Lower Bound" _col(50) "Upper Bound" _col(64) "than Control?" _col(80) "than Control?"; #delimit cr di in smcl in gr "{hline 9}{c +}{hline 82}" /* Output for control */ #delimit ; di as smcl in gr %8s abbrev("`lab`control'' ",8) " {c |}" in ye _col(12) %9.0g `control_mean' _col(30) "---" _col(44) "---" _col(58) "---" _col(69) "---" _col(85) "---"; #delimit cr /* Output for all treatments excluding control */ local i = 0 foreach group of local list{ local i = `i' + 1 if mod(`i',`separator')==0{ di as smcl in gr "{hline 9}{c +}{hline 82}" } if "`group'" == "."{ local g = "miss" local shortlab = "." } else{ local g = `group' local shortlab = abbrev("`lab`g''",8) } #delimit ; di as smcl in gr %8s "`shortlab'" " {c |}" in ye _col(12) %9.0g `mean`g'' _col(24) %9.0g `diff`g'' _col(38) %9.0g `lb`g'' _col(52) %9.0g `ub`g'' _col(69) %3s "`greater`g''" _col(85) %3s "`less`g''"; #delimit cr } /* Bottom line and notes */ di as smcl in gr "{hline 9}{c BT}{hline 82}" local shortfact = abbrev("`fact'",8) di as smcl in gr _col(6) "Diff = mean(`shortfact')-mean(control)" di as smcl in gr _col(6) "Greater than mean(control) if Diff > " %9.0g `criterion' di as smcl in gr _col(6) "Less than mean(control) if Diff < -" %9.0g `criterion' } /* Values to be returned in r() */ return clear return local fact_var "`fact'" return local resp_var "`resp'" return scalar confidence = `ci' return scalar side = `side' return scalar df = `df' return scalar groups = `k' return scalar reps = `n' return scalar N = `N' return scalar mse = `mse' return scalar d = `d' return scalar criterion = `criterion' return scalar control = `control' end /* Program d_table Contains four matrices of the Dunnett table values Takes arguments side, ci, df, and k Returns local value d containing table value */ capture program drop d_table program define d_table, rclass args side ci df k /* assign values i and j for grabbing table value from matrix */ /* j is number of treatments excluding control */ local j = `k'-1 /* Taking the conservative value for i (df) */ if `df'<=20{ local i = `df'-4 } if `df'>20 & `df'<24{ local i = 16 } if `df'>=24 & `df'<30{ local i = 17 } if `df'>=30 & `df'<40{ local i = 18 } if `df'>=40 & `df'<60{ local i = 19 } if `df'>=60 & `df'<120{ local i = 20 } if `df'==120{ local i = 21 } if `df'>120{ local i = 22 } /* two sided confidence intervals / alpha=0.05 */ if `side' == 2 & `ci' == 95{ capture matrix clear d_2_05 #delimit ; matrix input d_2_05 = (2.57,3.03,3.29,3.48,3.62,3.73,3.82,3.90,3.97,4.03,4.09,4.14,4.26,4.42\ 2.45,2.86,3.10,3.26,3.39,3.49,3.57,3.64,3.71,3.76,3.81,3.86,3.97,4.11\ 2.36,2.75,2.97,3.12,3.24,3.33,3.41,3.47,3.53,3.58,3.63,3.67,3.78,3.91\ 2.31,2.67,2.88,3.02,3.13,3.22,3.29,3.35,3.41,3.46,3.50,3.54,3.64,3.76\ 2.26,2.61,2.81,2.95,3.05,3.14,3.20,3.26,3.32,3.36,3.40,3.44,3.53,3.65\ 2.23,2.57,2.76,2.89,2.99,3.07,3.14,3.19,3.24,3.29,3.33,3.36,3.45,3.57\ 2.20,2.53,2.72,2.84,2.94,3.02,3.08,3.14,3.19,3.23,3.27,3.30,3.39,3.50\ 2.18,2.50,2.68,2.81,2.90,2.98,3.04,3.09,3.14,3.18,3.22,3.25,3.34,3.45\ 2.16,2.48,2.65,2.78,2.87,2.94,3.00,3.06,3.10,3.14,3.18,3.21,3.29,3.40\ 2.14,2.46,2.63,2.75,2.84,2.91,2.97,3.02,3.07,3.11,3.14,3.18,3.26,3.36\ 2.13,2.44,2.61,2.73,2.82,2.89,2.95,3.00,3.04,3.08,3.12,3.15,3.23,3.33\ 2.12,2.42,2.59,2.71,2.80,2.87,2.92,2.97,3.02,3.06,3.09,3.12,3.20,3.30\ 2.11,2.41,2.58,2.69,2.78,2.85,2.90,2.95,3.00,3.03,3.07,3.10,3.18,3.27\ 2.10,2.40,2.56,2.68,2.76,2.83,2.89,2.94,2.98,3.01,3.05,3.08,3.16,3.25\ 2.09,2.39,2.55,2.66,2.75,2.81,2.87,2.92,2.96,3.00,3.03,3.06,3.14,3.23\ 2.09,2.38,2.54,2.65,2.73,2.80,2.86,2.90,2.95,2.98,3.02,3.05,3.12,3.22\ 2.06,2.35,2.51,2.61,2.70,2.76,2.81,2.86,2.91,2.94,2.97,3.00,3.07,3.16\ 2.04,2.32,2.47,2.58,2.66,2.72,2.77,2.82,2.86,2.89,2.92,2.95,3.02,3.11\ 2.02,2.29,2.44,2.54,2.62,2.68,2.73,2.77,2.81,2.85,2.87,2.90,2.97,3.06\ 2.00,2.27,2.41,2.51,2.58,2.64,2.69,2.73,2.77,2.80,2.83,2.86,2.92,3.00\ 1.98,2.24,2.38,2.47,2.55,2.60,2.65,2.69,2.73,2.76,2.79,2.71,2.87,2.95\ 1.96,2.21,2.35,2.44,2.51,2.57,2.61,2.65,2.69,2.72,2.74,2.77,2.83,2.91); #delimit cr local d = d_2_05[`i',`j'] matrix drop d_2_05 } /* two sided confidence intervals / alpha=0.01 */ if `side' == 2 & `ci' == 99{ capture matrix drop d_2_01 #delimit ; matrix input d_2_01 = (4.03,4.63,4.98,5.22,5.41,5.56,5.69,5.80,5.89,5.98,6.05,6.12,6.30,6.52\ 3.71,4.21,4.51,4.71,4.87,5.00,5.10,5.20,5.28,5.35,5.41,5.47,5.62,5.81\ 3.50,3.95,4.21,4.39,4.53,4.64,4.74,4.82,4.89,4.95,5.01,5.06,5.19,5.36\ 3.36,3.77,4.00,4.17,4.29,4.40,4.48,4.56,4.62,4.68,4.73,4.78,4.90,5.05\ 3.25,3.63,3.85,4.01,4.12,4.22,4.30,4.37,4.43,4.48,4.53,4.57,4.68,4.82\ 3.17,3.53,3.74,3.88,3.99,4.08,4.16,4.22,4.28,4.33,4.37,4.42,4.52,4.65\ 3.11,3.45,3.65,3.79,3.89,3.98,4.05,4.11,4.16,4.21,4.25,4.29,4.39,4.52\ 3.05,3.39,3.58,3.71,3.81,3.89,3.96,4.02,4.07,4.12,4.16,4.19,4.29,4.41\ 3.01,3.33,3.52,3.65,3.74,3.82,3.89,3.94,3.99,4.04,4.08,4.11,4.20,4.32\ 2.98,3.29,3.47,3.59,3.69,3.76,3.83,3.88,3.93,3.97,4.01,4.05,4.13,4.24\ 2.95,3.25,3.43,3.55,3.64,3.71,3.78,3.83,3.88,3.92,3.95,3.99,4.07,4.18\ 2.92,3.22,3.39,3.51,3.60,3.67,3.73,3.78,3.83,3.87,3.91,3.94,4.02,4.13\ 2.90,3.19,3.36,3.47,3.56,3.63,3.69,3.74,3.79,3.83,3.86,3.90,3.98,4.08\ 2.88,3.17,3.33,3.44,3.53,3.60,3.66,3.71,3.75,3.79,3.83,3.86,3.94,4.04\ 2.86,3.15,3.31,3.42,3.50,3.57,3.63,3.68,3.72,3.76,3.79,3.83,3.90,4.00\ 2.85,3.13,3.29,3.40,3.48,3.55,3.60,3.65,3.69,3.73,3.77,3.80,3.87,3.97\ 2.80,3.07,3.22,3.32,3.40,3.47,3.52,3.57,3.61,3.64,3.68,3.70,3.78,3.87\ 2.75,3.01,3.15,3.25,3.33,3.39,3.44,3.49,3.52,3.56,3.59,3.62,3.69,3.78\ 2.70,2.95,3.09,3.19,3.26,3.32,3.37,3.41,3.44,3.48,3.51,3.53,3.60,3.68\ 2.66,2.90,3.03,3.12,3.19,3.25,3.29,3.33,3.37,3.40,3.42,3.45,3.51,3.59\ 2.62,2.85,2.97,3.06,3.12,3.18,3.22,3.26,3.29,3.32,3.35,3.37,3.43,3.51\ 2.58,2.79,2.92,3.00,3.06,3.11,3.15,3.19,3.22,3.25,3.27,3.29,3.35,3.42); #delimit cr local d = d_2_01[`i',`j'] matrix drop d_2_01 } /* one sided confidence intervals / alpha=0.05 */ if `side' == 1 & `ci' == 95{ capture matrix drop d_1_05 #delimit ; matrix input d_1_05 = (2.02,2.44,2.68,2.85,2.98,3.08,3.16,3.24,3.30\ 1.94,2.34,2.56,2.71,2.83,2.92,3.00,3.07,3.12\ 1.89,2.27,2.48,2.62,2.73,2.82,2.89,2.95,3.01\ 1.86,2.22,2.42,2.55,2.66,2.74,2.81,2.87,2.92\ 1.83,2.18,2.37,2.50,2.60,2.68,2.75,2.81,2.86\ 1.81,2.15,2.34,2.47,2.56,2.64,2.70,2.76,2.81\ 1.80,2.13,2.31,2.44,2.53,2.60,2.67,2.72,2.77\ 1.78,2.11,2.29,2.41,2.50,2.58,2.64,2.69,2.74\ 1.77,2.09,2.27,2.39,2.48,2.55,2.61,2.66,2.71\ 1.76,2.08,2.25,2.37,2.46,2.53,2.59,2.64,2.69\ 1.75,2.07,2.24,2.36,2.44,2.51,2.57,2.62,2.67\ 1.75,2.06,2.23,2.34,2.43,2.50,2.56,2.61,2.65\ 1.74,2.05,2.22,2.33,2.42,2.49,2.54,2.59,2.64\ 1.73,2.04,2.21,2.32,2.41,2.48,2.53,2.58,2.62\ 1.73,2.03,2.20,2.31,2.40,2.47,2.52,2.57,2.61\ 1.72,2.03,2.19,2.30,2.39,2.46,2.51,2.56,2.60\ 1.71,2.01,2.17,2.28,2.36,2.43,2.48,2.53,2.57\ 1.70,1.99,2.15,2.25,2.33,2.40,2.45,2.50,2.54\ 1.68,1.97,2.13,2.23,2.31,2.37,2.42,2.47,2.51\ 1.67,1.95,2.10,2.21,2.28,2.35,2.39,2.44,2.48\ 1.66,1.93,2.08,2.18,2.26,2.32,2.37,2.41,2.45\ 1.64,1.92,2.06,2.16,2.23,2.29,2.34,2.38,2.42); #delimit cr local d = d_1_05[`i',`j'] matrix drop d_1_05 } /* two sided confidence intervals / alpha=0.01 */ if `side' == 1 & `ci' == 99{ capture matrix drop d_1_01 #delimit ; matrix input d_1_01 = (3.37,3.90,4.21,4.43,4.60,4.73,4.85,4.94,5.03\ 3.14,3.61,3.88,4.07,4.21,4.33,4.43,4.51,4.59\ 3.00,3.42,3.66,3.83,3.96,4.07,4.15,4.23,4.30\ 2.90,3.29,3.51,3.67,3.79,3.88,3.96,4.03,4.09\ 2.82,3.19,3.40,3.55,3.66,3.75,3.82,3.89,3.94\ 2.76,3.11,3.31,3.45,3.56,3.64,3.71,3.78,3.83\ 2.72,3.06,3.25,3.38,3.48,3.56,3.63,3.69,3.74\ 2.68,3.01,3.19,3.32,3.42,3.50,3.56,3.62,3.67\ 2.65,2.97,3.15,3.27,3.37,3.44,3.51,3.56,3.61\ 2.62,2.94,3.11,3.23,3.32,3.40,3.46,3.51,3.56\ 2.60,2.91,3.08,3.20,3.29,3.36,3.42,3.47,3.52\ 2.58,2.88,3.05,3.17,3.26,3.33,3.39,3.44,3.48\ 2.57,2.86,3.03,3.14,3.23,3.30,3.36,3.41,3.45\ 2.55,2.84,3.01,3.12,3.21,3.27,3.33,3.38,3.42\ 2.54,2.83,2.99,3.10,3.18,3.25,3.31,3.36,3.40\ 2.53,2.81,2.97,3.08,3.17,3.23,3.29,3.34,3.38\ 2.49,2.77,2.92,3.03,3.11,3.17,3.22,3.27,3.31\ 2.46,2.72,2.87,2.97,3.05,3.11,3.16,3.21,3.24\ 2.42,2.68,2.82,2.92,2.99,3.05,3.10,3.14,3.18\ 2.39,2.64,2.78,2.87,2.94,3.00,3.04,3.08,3.12\ 2.36,2.60,2.73,2.82,2.89,2.94,2.99,3.03,3.06\ 2.33,2.56,2.68,2.77,2.84,2.89,2.93,2.97,3.00); #delimit cr local d = d_1_01[`i',`j'] matrix drop d_1_01 } /* return table value in r(d) */ return clear return scalar d = `d' end