Here, I am presenting the Stata code necessary to fit the models in Chapter 7 of Twisk (2006) using -runmlwin-. The data for the chapter are available here.
// Define MLwiN path
global MLwiN_path C:\Program Files\MLwiN v2.27\i386\mlwin.exe
// Section 7.2: "Multivariate multilevel analysis: the MLwiM approach"
// (MLwiN approach = wide data format)
// Read in wide format data
insheet total_cholesterol systolic_blood_pressure medical_doctor age id ///
using "D:\twisk data sets\multivariate.dat", clear
// Table 7.1
// Table in book doesn't seem to be super-accurate
list id total_cholesterol systolic_blood_pressure medical_doctor age in 1/3
// Generate constant
gen cons = 1
// Output 7.2
// - Single-level multivariate HLM model
// - Random effects parameters are partitioned residual
// variance only, not random intercepts
runmlwin (total_cholesterol cons age, eq(1)) ///
(systolic_blood_pressure cons age, eq(2)), ///
level1(id: (cons, eq(1)) (cons, eq(2))) nopause
// Output 7.3
// - Single-level univariate model for one outcome
runmlwin total_cholesterol cons age, level1(id: cons) nopause
// Output 7.4
// - Single-level univariate model for other outcome
runmlwin systolic_blood_pressure cons age, level1(id: cons) nopause
// Output 7.5
// - Single-level MANCOVA
quietly manova total_cholesterol systolic_blood_pressure = c.age
mvreg
// Output 7.6
// - Single-level multivariate HLM model
// - age coefficients constrained to be equal
// Approach via externally defining a constraint
constraint def 1 [FP1]age = [FP2]age
runmlwin (total_cholesterol cons age, eq(1)) ///
(systolic_blood_pressure cons age, eq(2)), ///
level1(id: (cons, eq(1)) (cons, eq(2))) ///
constraints(1) ///
nopause
// Output 7.6
// - Single-level multivariate HLM model
// - age coefficients constrained to be equal
// Approach via constraining in runmlwin
runmlwin (total_cholesterol cons, equation(1)) ///
(systolic_blood_pressure cons, equation(2)) ///
(age, equation(1/2)) ///
, ///
level1(id: (cons, equation(1)) (cons, equation(2))) ///
nosort nopause
// Output 7.7
// - Multilevel multivariate HLM model
// - Age coefficients constrained to be equal
// - Random intercepts for different doctors
// Approach via constraining in runmlwin
runmlwin (total_cholesterol cons, eq(1)) ///
(systolic_blood_pressure cons, eq(2)) ///
(age, equation(1/2)) ///
, ///
level1(id: (cons, eq(1)) (cons, eq(2))) ///
level2(medical_doctor: (cons, eq(1)) (cons, eq(2))) ///
nosort nopause
// Output 7.8
// - Multilevel multivariate HLM model
// - Age coefficients constrained to be equal
// - Random intercepts for different doctors
// - Random slope for age coefficient
// Approach via constraining in runmlwin
runmlwin (total_cholesterol cons, eq(1)) ///
(systolic_blood_pressure cons, eq(2)) ///
(age, equation(1/2)) ///
, ///
level1(id: (cons, eq(1)) (cons, eq(2))) ///
level2(medical_doctor: (cons, eq(1)) (cons, eq(2)) (age, eq(1/2))) ///
nosort nopause
// Section 7.3: "Multivariate multilevel analysis: the general approach"
// (general approach = long data format)
// Read in long format data set
insheet z_outcome medical_doctor age variable id ///
using "D:\twisk data sets\multivariate_z.dat", clear
// Table 7.2
// Table in book doesn't seem to be super-accurate
list id z_outcome medical_doctor age variable in 1/4
// Generate constant
gen cons = 1
// Output 7.10
// - Random intercept at doctor level
runmlwin (z_outcome cons age), ///
level1(variable: cons) ///
level2(id: cons) nopause
// Output 7.11
// - Random intercept at doctor level
runmlwin (z_outcome cons age), ///
level1(variable: cons) ///
level2(id: cons) ///
level3(medical_doctor: cons) ///
nopause
// Output 7.12
// - Random intercept at doctor level
// - Random intercept at patient level
// - Random slope for age at patient level
runmlwin (z_outcome cons age), ///
level1(variable: cons) ///
level2(id: cons age) ///
level3(medical_doctor: cons) ///
nopause
// Output 7.13
// - Random intercept at doctor level
// - Random intercept at patient level
// - Random slope for age at doctor level
runmlwin (z_outcome cons age), ///
level1(variable: cons) ///
level2(id: cons) ///
level3(medical_doctor: cons age) ///
nopause
// Section 7.4 "Comments"
// Covert to wide format
reshape wide z_outcome, i(id) j(variable)
rename z_outcome1 total_cholesterol
rename z_outcome2 systolic_blood_pressure
// Output 7.14
// - Random intercept at doctor level
// - Random intercept at patient level
// - Random slope for age at doctor level
// Estimated via the "MLwiN approach"
runmlwin (total_cholesterol cons, eq(1)) ///
(systolic_blood_pressure cons, eq(2)) ///
(age, eq(1/2)) ///
, ///
level1(id: (cons, eq(1)) (cons, eq(2))) ///
level2(medical_doctor: (cons, eq(1)) (cons, eq(2)) (age, eq(1/2))) ///
nopause
References
Leckie, George, and Chris Charlton. 2013. "runmlwin. A Program to Run the MLwiN Multilevel Modeling Software from within Stata." Journal of Statistical Software 52(11):1-40.Rasbash, John, Fiona Steele, William J. Browne, and Harvey Goldstein. 2012. A User's Guide to MLwiN Version 2.26. Center for Multilevel Modeling, University of Bristol.
Twisk, Jos W. R. 2006. Applied Multilevel Analysis. A Practical Guide. Cambridge University Press. doi: 10.1017/CBO9780511610806