/*______________________________________________________________________________
	
	PAPER: "PRACTICAL STRATEGIES FOR HANDLING NUMERICAL DIFFICULTIES WITH MULTIPLE IMPUTATION ALGORITHMS"
	Authors: C. Nguyen, J. Carlin, K. Lee
	
	This file provides Stata code for analyses of data from the Longitudinal Study of Australian Children (LSAC)
	
	Nb. The dataset "LSAC_Kcohort.dta" cannot be provided by authors, but access to LSAC data can be requested at
	https://dataverse.ada.edu.au/dataverse/ncld 
	
	// THE ANALYSIS MODEL USES THE FOLLOWING VARIABLES:
	
	EXPOSURE: 
	bmiz: BMI z-score (exposure variable) 
	
	COVARIATES:
	male: gender (0=female, 1=male) 
	age: child's age (months)
	indig: child's indigenous status (0=no, 1=yes)
	sdq: child mental health (SDQ total score, range 0-35)
	mat_edu: mother completed high school (0=no, 1=yes)
	mat_lang: Mother's main language (0=English, 1=not English)
	mat_k6: Mother's emotional distress (Kessler-6 score, range 0-24)
	mat_work: mother's work status (0=not working, 1=working)
	seifa: neighbourhood disadvantage (Socio-Economic Indexes for Areas, mean~1000, SD~100)

	OUTCOME VARIABLE:
	hrqol_w3_1 to hrqol_w3_23: 23 items from PedsQL (Health related quality of life [HRQol]) scale measured at wave 3 (range from 1 to 5)
	hrqol_w3_bin: Binary HRQoL outcome variable measured at wave 3 (derived from the 23-item PedsQL scale)  (0=no problems, 1=HRQoL problems). 
		
	Nb. In order to derive the binary outcome, the individual items are reverse scored ( 1=100, 2=75, 3=50, 4=25, 5=0) and averaged to produce a total score (range 0-100),
	which is dichotomised (at 1 standard deviation above the population mean) to produce a binary variable 
				
	
	// THE IMPUTATION MODEL INCLUDES:
	
	- All variables in the analysis model
	- The auxiliary variable is HRQoL measured at wave 1, included either as 
		individual items (hrqol_w1_1 to hrqol_w1_21) or as a binary variable at the total score level (hrqol_w1_bin)
		
	
_______________________________________________________________________________*/
capture log close
version 15
set more off

log using "an_impute.log", replace

*_______________________________________________________________________________
* DEFINING MACROS
* Optional - using macros as a convenient way to refer to items in the HRQoL scales

* Define global macro "hrqol_items_w3" representing all of the HRQoL items at wave 3 (i.e. items that make up the outcome variable)
global hrqol_items_w3 hrqol_w3_1 hrqol_w3_2 hrqol_w3_3 hrqol_w3_4 hrqol_w3_5 hrqol_w3_6 hrqol_w3_7 hrqol_w3_8 //
hrqol_w3_9 hrqol_w3_10 hrqol_w3_11 hrqol_w3_12 hrqol_w3_13 hrqol_w3_14 hrqol_w3_15 hrqol_w3_16 //
hrqol_w3_17 hrqol_w3_18 hrqol_w3_19 hrqol_w3_20 hrqol_w3_21 hrqol_w3_22 hrqol_w3_23


* Define global macro "hrqol_items_w1" for all of the HRQoL items at wave 1 (i.e. auxiliary variables)
global hrqol_items_w1 hrqol_w3_1 hrqol_w1_2 hrqol_w1_3 hrqol_w1_4 hrqol_w1_5 hrqol_w1_6 hrqol_w1_7 hrqol_w1_8 //
hrqol_w1_9 hrqol_w1_10 hrqol_w1_11 hrqol_w1_12 hrqol_w1_13 hrqol_w1_14 hrqol_w1_15 hrqol_w1_16 //
hrqol_w1_17 hrqol_w1_18 hrqol_w1_19 hrqol_w1_20 hrqol_w1_21 hrqol_w1_22 hrqol_w1_23


*_______________________________________________________________________________
* COMPLETE CASE ANALYSIS
use "LSAC_Kcohort.dta", clear
	
logistic hrqol_w3_bin bmiz male age indig sdq mat_edu mat_lang mat_k6 mat_work seifa


/*******************************************************************************

		MULTIPLE IMPUTATION ANALYSES
							
*******************************************************************************/

/*______________________________________________________________________________
ORIGINAL MODEL
- MICE imputation
- Impute HRQoL items at wave 3 (i.e. items used to derive the outcome variable) at the item level using ordinal logistic regression	
- Impute HRQoL items at wave 1 (i.e. auxiliary variables) at the item level using ordinal logistic regression

_______________________________________________________________________________*/
use "LSAC_Kcohort.dta", clear

* Multiple imputation
mi set flong
mi register imputed $hrqol_items_w3 $hrqol_items_w1 bmiz age sdq mat_k6 indig mat_edu mat_lang mat_work 
mi impute chained (regress) bmiz age  sdq mat_k6 ///
(logit) indig  mat_edu mat_lang mat_work (ologit) $hrqol_items_w3 $hrqol_items_w1 ///
= male seifa , add(30) rseed(3032189) 

// No imputations generated because model did not run 


/*______________________________________________________________________________
STRATEGY 1
- As original model, but using the "augment" option
_______________________________________________________________________________*/
use "LSAC_Kcohort.dta", clear

* Multiple imputation
mi set flong
mi register imputed $hrqol_items_w3 $hrqol_items_w1 bmiz age sdq mat_k6 indig  mat_edu mat_lang mat_work 
mi impute chained (regress) bmiz age  sdq mat_k6 ///
(logit) indig  mat_edu mat_lang  mat_work (ologit) $hrqol_items_w3 $hrqol_items_w1 ///
= male seifa , add(30) augment rseed(7269388) 

// No imputations generated because model did not run 

/*______________________________________________________________________________
STRATEGY 2
- MICE imputation
- Impute HRQoL items at wave 3 (i.e. items used to derive the outcome variable) at the item level  using linear regression
- Impute HRQoL items at wave 1 (i.e. auxiliary variables) at the item level using linear regression
_______________________________________________________________________________*/
use "LSAC_Kcohort.dta", clear

* Multiple imputation
mi set flong
mi register imputed $hrqol_items_w3 $hrqol_items_w1 bmiz age  sdq mat_k6 indig mat_edu mat_lang mat_work 
mi impute chained (regress) bmiz age  sdq mat_k6 $hrqol_items_w3 $hrqol_items_w1 ///
(logit) indig  mat_edu mat_lang mat_work  ///
= male seifa , add(30) rseed(338711189) 

* PedsQL (HRQoL) items are transformed to 0-100 scale
foreach var of varlist $hrqol_items_w3 {
		
		quietly {
		mi passive: gen `var'_100_imp = (125 -25*`var') 
	}
}

* Generate HRQoL total score
egen hrqol_total_imp= rowmean(hrqol*100_imp)

* Dichotomise HRQoL total score
mi passive: gen hrqol_w3_bin_imp =1 if hrqol_total_imp<65.42
mi passive: replace hrqol_w3_bin_imp =0 if hrqol_total_imp>=65.42 & hrqol_total_imp <.

* Run the analysis model
mi estimate: logistic hrqol_w3_bin_imp bmiz male age indig sdq mat_edu mat_lang mat_k6 mat_work seifa


/*______________________________________________________________________________
STRATEGY 3
- MICE imputation
- Impute HRQoL items at wave 3 (i.e. items used to derive the outcome variable) at the item level using predictive mean matching (PMM)
- Impute HRQoL items at wave 1 (i.e. auxiliary variables) at the item level using predictive mean matching (PMM)
_______________________________________________________________________________*/
use "LSAC_Kcohort.dta", clear

* Multiple imputation
mi set flong
mi register imputed $hrqol_items_w3 $hrqol_items_w1 bmiz age  sdq mat_k6 indig mat_edu mat_lang mat_work 
mi impute chained (regress) bmiz age  sdq mat_k6 ///
(logit) indig  mat_edu mat_lang mat_work (pmm, knn(5)) $hrqol_items_w3 $hrqol_items_w1 ///
= male seifa , add(30) rseed(871686) 

* PedsQL (HRQoL) items are transformed to 0-100 scale
foreach var of varlist $hrqol_items_w3 {
		
		quietly {
		mi passive: gen `var'_100_imp = (125 -25*`var') 
	}
}

* Generate HRQoL total score
egen hrqol_total_imp= rowmean(hrqol*100_imp)

* Dichotomise HRQoL total score
mi passive: gen hrqol_w3_bin_imp =1 if hrqol_total_imp<65.42
mi passive: replace hrqol_w3_bin_imp =0 if hrqol_total_imp>=65.42 & hrqol_total_imp <.

* Run the analysis model
mi estimate: logistic hrqol_w3_bin_imp bmiz male age indig sdq mat_edu mat_lang mat_k6 mat_work seifa


/*______________________________________________________________________________
STRATEGY 4
- MICE imputation
- Impute HRQoL items at wave 3 (i.e. items used to derive the outcome variable) using ordinal logistic regression
- Impute auxiliary HRQoL (wave 1) at the total score level using logistic regression
_______________________________________________________________________________*/
use "LSAC_Kcohort.dta", clear

* Multiple imputation
mi set flong
mi register imputed $hrqol_items_w3 hrqol_w1_bin bmiz age sdq mat_k6 indig mat_edu mat_lang mat_work 
mi impute chained (regress) bmiz age sdq mat_k6 ///
(logit) indig  mat_edu mat_lang mat_work hrqol_w1_bin (ologit) $hrqol_items_w3 ///
= male seifa , add(30) rseed(6834368) 

// No imputations generated because model did not run 


/*______________________________________________________________________________
STRATEGY 5
- MICE imputation
- Impute HRQoL items at wave 3 (i.e. items used to derive the outcome variable) using ordinal logistic regression
- Impute auxiliary HRQoL (wave 1) at the total score level using logistic regression
- Imputation model uses the “augment” option
_______________________________________________________________________________*/
use "LSAC_Kcohort.dta", clear

* Multiple imputation
mi set flong
mi register imputed $hrqol_items_w3 hrqol_w1_bin bmiz age sdq mat_k6 indig mat_edu mat_lang mat_work 
mi impute chained (regress) bmiz age sdq mat_k6 ///
(logit) indig  mat_edu mat_lang  mat_work hrqol_w1_bin (ologit) $hrqol_items_w3  ///
= male seifa , add(30) augment rseed(9847809)

// No imputations generated because model did not run 


/*______________________________________________________________________________
STRATEGY 6
- MICE imputation
- Impute HRQoL outcome (wave 3) at total score level using logistic regression
- Impute HRQoL items at wave 1 (i.e. auxiliary variables) at the item level using ordinal logistic regression
_______________________________________________________________________________*/
use "LSAC_Kcohort.dta", clear

* Multiple imputation
mi set flong
mi register imputed hrqol_w3_bin $hrqol_items_w1 bmiz age sdq mat_k6 indig mat_edu mat_lang mat_work 
mi impute chained (regress) bmiz age  sdq mat_k6 ///
(logit) indig  mat_edu mat_lang  mat_work  hrqol_w3_bin (ologit) $hrqol_items_w1 ///
= male seifa , add(30) rseed(7321735) 

// No imputations generated because model did not run 

/*______________________________________________________________________________
STRATEGY 7
- MICE imputation
- Impute HRQoL outcome (wave 3) at total score level using logistic regression
- Impute HRQoL items at wave 1 (i.e. auxiliary variables) at the item level using ordinal logistic regression
- Imputation model uses the “augment” option
_______________________________________________________________________________*/
use "LSAC_Kcohort.dta", clear

* Multiple imputation
mi set flong
mi register imputed hrqol_w3_bin $hrqol_items_w1 bmiz age sdq mat_k6 indig mat_edu mat_lang mat_work 
mi impute chained (regress) bmiz age  sdq mat_k6 ///
(logit) indig  mat_edu mat_lang mat_work hrqol_w3_bin (ologit) $hrqol_items_w1 ///
= male seifa , add(30) rseed(398717) augment 

// No imputations generated because model did not run 


/*______________________________________________________________________________
STRATEGY 8
- MICE imputation
- Impute HRQoL outcome (wave 3) at total score level using logistic regression
- Impute auxiliary HRQoL (wave 1) at total score level using logistic regression
_______________________________________________________________________________*/
use "LSAC_Kcohort.dta", clear

* Multiple imputation
mi set flong
mi register imputed hrqol_w3_bin hrqol_w1_bin bmiz age sdq mat_k6 indig mat_edu mat_lang mat_work 
mi impute chained (regress) bmiz age sdq mat_k6 ///
(logit) indig mat_edu mat_lang mat_work hrqol_w3_bin hrqol_w1_bin  ///
= male seifa , add(30) rseed(5485577) 


* Run the analysis model
mi estimate: logistic hrqol_w3_bin bmiz male age indig sdq mat_edu mat_lang mat_k6 mat_work seifa


/*______________________________________________________________________________
STRATEGY 9
- MVN imputation
- Impute HRQoL items at wave 3 (i.e. items used to derive the outcome variable) at the item level using MVNI
- Impute HRQoL items at wave 1 (i.e. auxiliary variables) at the item level using MVNI
_______________________________________________________________________________*/
use "LSAC_Kcohort.dta", clear

* Multiple imputation
mi set flong
mi register imputed $hrqol_items_w3 $hrqol_items_w1 bmiz age sdq mat_k6 indig mat_edu mat_lang mat_work 
mi impute mvn $hrqol_items_w3 $hrqol_items_w1 bmiz age sdq mat_k6 indig  mat_edu mat_lang  mat_work ///
= male seifa , add(30) rseed(6938711) 


* PedsQL (HRQoL) items are transformed to 0-100 scale
foreach var of varlist $hrqol_items_w3 {
		
		quietly {
		mi passive: gen `var'_100_imp = (125 -25*`var') 
	}
}

* Generate PEDSQL total score
egen hrqol_total_imp= rowmean(hrqol*100_imp)

* Dichotomise PEDSQL total score
mi passive: gen hrqol_w3_bin_imp =1 if hrqol_total_imp<65.42
mi passive: replace hrqol_w3_bin_imp =0 if hrqol_total_imp>=65.42 & hrqol_total_imp <.

* Run the analysis model
mi estimate: logistic hrqol_w3_bin_imp bmiz male age indig sdq mat_edu mat_lang mat_k6 mat_work seifa

/*______________________________________________________________________________
STRATEGY 10
- MVN imputation
- Impute HRQoL items at wave 3 (i.e. items used to derive the outcome variable) at the item level as indicator variables using MVNI
- Impute HRQoL items at wave 1 (i.e. auxiliary variables) at the item level as indicator variables using MVNI
- To obtain ordinal values for HRQoL items, the HRQoL items are imputed as indicator variables followed by 
	projected-distance based rounding to obtain ordinal values ( Galati et al. 2014. Journal of Statistical Computation and Simulation, 84:4, 798-811, DOI: 10.1080/00949655.2012.727815 )
_______________________________________________________________________________*/
use "LSAC_Kcohort.dta", clear

* Create indicator variables for each HRQoL item 
foreach var of varlist $hrqol_items_w3 $hrqol_items_w1 {
	xi i.`var'
	rename _I`var'_2 `var'_2
	rename _I`var'_3 `var'_3
	rename _I`var'_4 `var'_4
	rename _I`var'_5 `var'_5
	
}

* Create global macros for all of the indicator variables at wave 3 and wave 1 (for convenience - to avoid repeating variable names)
global hrqol_items_w3_ind hrqol_w3_1_2 hrqol_w3_1_3 hrqol_w3_1_4 hrqol_w3_1_5 ///
hrqol_w3_2_2 hrqol_w3_2_3 hrqol_w3_2_4 hrqol_w3_2_5  ///
hrqol_w3_3_2 hrqol_w3_3_3 hrqol_w3_3_4 hrqol_w3_3_5  ///
hrqol_w3_4_2 hrqol_w3_4_3 hrqol_w3_4_4 hrqol_w3_4_5  ///
hrqol_w3_5_2 hrqol_w3_5_3 hrqol_w3_5_4 hrqol_w3_5_5  ///
hrqol_w3_6_2 hrqol_w3_6_3 hrqol_w3_6_4 hrqol_w3_6_5  ///
hrqol_w3_7_2 hrqol_w3_7_3 hrqol_w3_7_4 hrqol_w3_7_5  ///
hrqol_w3_8_2 hrqol_w3_8_3 hrqol_w3_8_4 hrqol_w3_8_5  ///
hrqol_w3_9_2 hrqol_w3_9_3 hrqol_w3_9_4 hrqol_w3_9_5  ///
hrqol_w3_10_2 hrqol_w3_10_3 hrqol_w3_10_4 hrqol_w3_10_5  /// 
hrqol_w3_11_2 hrqol_w3_11_3 hrqol_w3_11_4 hrqol_w3_11_5  ///
hrqol_w3_12_2 hrqol_w3_12_3 hrqol_w3_12_4 hrqol_w3_12_5  ///
hrqol_w3_13_2 hrqol_w3_13_3 hrqol_w3_13_4 hrqol_w3_13_5  ///
hrqol_w3_14_2 hrqol_w3_14_3 hrqol_w3_14_4 hrqol_w3_14_5  ///
hrqol_w3_15_2 hrqol_w3_15_3 hrqol_w3_15_4 hrqol_w3_15_5  ///
hrqol_w3_16_2 hrqol_w3_16_3 hrqol_w3_16_4 hrqol_w3_16_5  ///
hrqol_w3_17_2 hrqol_w3_17_3 hrqol_w3_17_4 hrqol_w3_17_5  ///
hrqol_w3_18_2 hrqol_w3_18_3 hrqol_w3_18_4 hrqol_w3_18_5  ///
hrqol_w3_19_2 hrqol_w3_19_3 hrqol_w3_19_4 hrqol_w3_19_5  ///
hrqol_w3_20_2 hrqol_w3_20_3 hrqol_w3_20_4 hrqol_w3_20_5  ///
hrqol_w3_21_2 hrqol_w3_21_3 hrqol_w3_21_4 hrqol_w3_21_5  /// 
hrqol_w3_22_2 hrqol_w3_22_3 hrqol_w3_22_4 hrqol_w3_22_5  ///
hrqol_w3_23_2 hrqol_w3_23_3 hrqol_w3_23_4 hrqol_w3_23_5 

global hrqol_items_w1_ind hrqol_w1_1_2 hrqol_w1_1_3 hrqol_w1_1_4 hrqol_w1_1_5 ///
hrqol_w1_2_2 hrqol_w1_2_3 hrqol_w1_2_4 hrqol_w1_2_5 ///
hrqol_w1_3_2 hrqol_w1_3_3 hrqol_w1_3_4 hrqol_w1_3_5 ///
hrqol_w1_4_2 hrqol_w1_4_3 hrqol_w1_4_4 hrqol_w1_4_5 ///
hrqol_w1_5_2 hrqol_w1_5_3 hrqol_w1_5_4 hrqol_w1_5_5 ///
hrqol_w1_6_2 hrqol_w1_6_3 hrqol_w1_6_4 hrqol_w1_6_5 ///
hrqol_w1_7_2 hrqol_w1_7_3 hrqol_w1_7_4 hrqol_w1_7_5 ///
hrqol_w1_8_2 hrqol_w1_8_3 hrqol_w1_8_4 hrqol_w1_8_5 ///
hrqol_w1_9_2 hrqol_w1_9_3 hrqol_w1_9_4 hrqol_w1_9_5 ///
hrqol_w1_10_2 hrqol_w1_10_3 hrqol_w1_10_4 hrqol_w1_10_5 ///
hrqol_w1_11_2 hrqol_w1_11_3 hrqol_w1_11_4 hrqol_w1_11_5 ///
hrqol_w1_12_2 hrqol_w1_12_3 hrqol_w1_12_4 hrqol_w1_12_5 ///
hrqol_w1_13_2 hrqol_w1_13_3 hrqol_w1_13_4 hrqol_w1_13_5 ///
hrqol_w1_14_2 hrqol_w1_14_3 hrqol_w1_14_4 hrqol_w1_14_5 ///
hrqol_w1_15_2 hrqol_w1_15_3 hrqol_w1_15_4 hrqol_w1_15_5 ///
hrqol_w1_16_2 hrqol_w1_16_3 hrqol_w1_16_4 hrqol_w1_16_5 ///
hrqol_w1_17_2 hrqol_w1_17_3 hrqol_w1_17_4 hrqol_w1_17_5 ///
hrqol_w1_18_2 hrqol_w1_18_3 hrqol_w1_18_4 hrqol_w1_18_5 ///
hrqol_w1_19_2 hrqol_w1_19_3 hrqol_w1_19_4 hrqol_w1_19_5 ///
hrqol_w1_20_2 hrqol_w1_20_3 hrqol_w1_20_4 hrqol_w1_20_5 ///
hrqol_w1_21_2 hrqol_w1_21_3 hrqol_w1_21_4 hrqol_w1_21_5 

* Multiple imputation
mi set flong
mi register imputed $hrqol_items_w3_ind $hrqol_items_w1_ind bmiz age  sdq mat_k6 indig  mat_edu mat_lang mat_work 
mi impute mvn $hrqol_items_w3_ind $hrqol_items_w1_ind bmiz age  sdq mat_k6 indig  mat_edu mat_lang  mat_work ///
= male seifa , add(30) rseed(5204175) 


// No imputations generated because model did not run 

/*______________________________________________________________________________
STRATEGY 11
- MVN imputation
- Impute HRQoL outcome (wave 3) at total score level 
- Impute auxiliary HRQoL (wave 1) at total score level 
- Adapting rounding performed after imputation to obtain the binary outcome variable for the analysis (Bernaards CA, Belin TR, Schafer JL. Robustness of a multivariate normal approximation for imputation of incomplete binary data. Statistics in Medicine 2007; 26:1368–1382.)
_______________________________________________________________________________*/
use "LSAC_Kcohort.dta", clear

* Multiple imputation
mi set flong
mi register imputed hrqol_w3_bin hrqol_w1_bin bmiz age  sdq mat_k6 indig  mat_edu mat_lang mat_work 
mi impute mvn hrqol_w3_bin hrqol_w1_bin bmiz age  sdq mat_k6 indig  mat_edu mat_lang  mat_work ///
= male seifa , add(30) rseed(7906128) 

* Adaptive rounding of hrqol_w3_bin
cap prog drop adround_mvn
program define adround_mvn
    args var
    qui sum `var' if _mi_m==0
    local omegabar  = `r(mean)'
    di "omegabar = `omegabar'"
    local threshold = `omegabar' - invnorm(`omegabar') * sqrt(`omegabar'*(1 - `omegabar'))
    replace `var' = 0 if `var' < `threshold' & _mi_m != 0
    replace `var' = 1 if `var' > `threshold' & _mi_m != 0
end

adround_mvn hrqol_w3_bin

* Run the analysis model
mi estimate: logistic hrqol_w3_bin bmiz male age indig sdq mat_edu mat_lang mat_k6 mat_work seifa


log close

