*! Author: Hong Il Yoo (h.i.yoo@durham.ac.uk) *! HIY 1.1.0 24 February 2019 program define lclogitcov2, sortpreserve version 13.1 if ("`e(cmd)'" != "lclogit2")&("`e(cmd)'" != "lclogitml2") error 301 local indepvars_rand "`e(indepvars_rand)'" local K : word count `indepvars_rand' syntax varlist(max=`K') [if] [in] [, NOkeep VARname(name) COVname(name) MATrix(name)] tempname up CB tempvar ncm **Check varlist includes indepvars in the choice model** local check : list varlist in indepvars_rand if `check' != 1 { display as error "some of specified variables do not have heterogeneous coefficients." error 197 } **Define macros to facilitate naming the covariance variable** local i = 0 foreach v of varlist `varlist' { local i = `i' + 1 local var`i' `v' } **Check variable names are not in use** if ("`varname'" == "") local varname var_ if ("`covname'" == "") local covname cov_ forvalues j = 1/`i' { capture confirm new variable `varname'`j' if (_rc != 0) { di as error "`varname'`j' already defined." exit 110 } if (`j'<`i') { forvalues k = `=`j'+1'/`i' { capture confirm new variable `covname'`j'`k' if (_rc != 0) { di as error "`covname'`j'`k' already defined." exit 110 } } } } ** Check that group, id and other explanatory variables are numeric ** foreach v of varlist `e(group)' `e(id)' `e(indepvars_rand)' `e(indepvars_share)' { capture confirm numeric variable `v' if _rc != 0 { display as error "variable `v' is not numeric." exit 498 } } **Mark prediction sample** marksample touse, novarlist **Generate variables to hold means, variances and covariances** forvalues j = 1/`i' { tempvar mean`var`j'' qui gen double `mean`var`j''' = 0 if `touse' } forvalues j = 1/`i' { qui gen double `varname'`j' = 0 if `touse' } forvalues j = 1/`i' { if (`j'<`i') { forvalues k = `=`j'+1'/`i' { qui gen double `covname'`j'`k' = 0 if `touse' } } } **Generate a binary indicator which equals one for the last obs on each agent** sort `e(id)' `e(group)' qui by `e(id)' : gen byte `ncm' = [_n==_N] if `touse' **Predict class shares** lclogitpr2 double `up' if `touse', up qui { **Compute mean taste parameter estimates** foreach v of varlist `varlist' { forvalues c = 1/`e(nclasses)' { replace `mean`v'' = `mean`v'' + `up'`c'*_b[Class`c':`v'] if `touse' } local coefname `coefname' `v' } **Compute variances and covariances** forvalues j = 1/`i' { forvalues c = 1/`e(nclasses)' { replace `varname'`j' = `varname'`j' + `up'`c'*(_b[Class`c':`var`j''] - `mean`var`j''')^2 if `touse' } label variable `varname'`j' `"variance of coef on `var`j''"' if (`j'<`i') { forvalues k = `=`j'+1'/`i' { forvalues c = 1/`e(nclasses)' { replace `covname'`j'`k' = `covname'`j'`k' + `up'`c'*(_b[Class`c':`var`j''] - `mean`var`j''')*(_b[Class`c':`var`k''] - `mean`var`k''') if `touse' } label variable `covname'`j'`k' `"cov b/w coefs on `var`j'' and `var`k''"' } } } } **Create the covariance matrix of choice model parameters** mat `CB' = J(`i',`i',.) forvalues j = 1/`i' { qui sum `varname'`j' if `ncm' == 1, meanonly matrix `CB'[`j', `j'] = r(mean) if (`j'<`i') { forvalues k = `=`j'+1'/`i' { qui sum `covname'`j'`k' if `ncm' == 1, meanonly matrix `CB'[`j', `k'] = r(mean) matrix `CB'[`k', `j'] = r(mean) } } } mat colnames `CB' = `coefname' mat rownames `CB' = `coefname' di as txt "" di as txt " Implied variances and covariances of random coefficients" di as txt " averaged across `e(id)' in the prediction sample." mat list `CB', noheader if ("`matrix'" != "") mat `matrix' = `CB' **Drop variance and covariance variables if option nokeep is specified** if "`nokeep'" != "" { forvalues j = 1/`i' { drop `varname'`j' if (`j'<`i') { forvalues k = `=`j'+1'/`i' { drop `covname'`j'`k' } } } } end