program mcmcmixed, eclass /* version 1.0, 5 jan 2012 */ /* sam schulhofer-wohl, federal reserve bank of minneapolis */ version 12.0 local mycmdline `0' _parse expand cmd op : 0, common(saving(string asis) iterate(integer) seed(integer) replace d0(real) delta0(real) nolog) /* allows fw, aw in the FE equation, no weights in the RE equation */ if `cmd_n'>2 { di "only one random-effects equation allowed." error 101 } else if `cmd_n'==1 { *just a regression mcmcreg `mycmdline' } else { *parse the estimation options local 0 ", `op_op'" syntax, saving(string asis) d0(real) delta0(name) [iterate(integer 100) seed(integer 12345) replace nolog] if "`log'"=="nolog" local showiter=0 else local showiter=1 *confirm we have somewhere to put the results, otherwise abort now if "`replace'"=="" capture confirm new file `saving' else capture save `saving', `replace' if _rc error _rc *parse the fixed-effects equation local 0 "`cmd_1'" syntax varlist(numeric) [if] [in] [fw aw] [, noconstant] marksample touse unab vars : `varlist' gettoken y x : vars local weightfe "`weight'" local expfe "`exp'" local constantfe "`constant'" if "`weightfe'"~="" { tempvar wfe qui gen double `wfe' `expfe' local usewfe=1 } else { local wfe "" local usewfe=0 } if "`weightfe'"=="aweight" local awfe=1 else local awfe=0 if "`constantfe'"=="noconstant" local cfe=0 else local cfe=1 *make sure we have either a rhs variable or a constant in the fixed-effects equation local nx : word count `x' if `nx'==0 & `cfe'==0 { di "fixed-effects equation must specify at least one independent variable or include a constant." error 101 } *parse the random-effects equation if strpos("`cmd_2'",":")==0 error 101 gettoken levelorig 0 : cmd_2, parse(":") gettoken junk 0 : 0, parse(": ") local varlist "" local constant "" syntax [varlist(numeric default=none)] [, noconstant] if subinstr("`varlist'"," ","",.)~="" unab z : `varlist' else local z "" markout `touse' `levelorig' `z', strok local constantre "`constant'" if "`constantre'"=="noconstant" local cre=0 else local cre=1 *make sure we have either a rhs variable or a constant in the random-effects equation local nz : word count `z' if `nz'==0 & `cre'==0 { di "random-effects equation must specify at least one independent variable or include a constant." error 101 } *store the original data tempfile temp qui save `temp', replace *keep only the data we want qui keep if `touse' *remove collinear variables _rmcoll `x', `constantfe' forcedrop local x `r(varlist)' local nx : word count `x' if `nx'>0 local usex 1 else local usex 0 _rmcoll `z', `constantre' forcedrop local z `r(varlist)' local nz : word count `z' if `nz'>0 local usez 1 else local usez 0 *identify and sort the groups tempvar levelvar egen double `levelvar'=group(`levelorig') sort `levelvar' qui sum `levelvar', meanonly local ng=r(max) *get number of observations local N=_N *parse delta0 tempname mydelta0 capture confirm matrix `delta0' if !_rc { if rowsof(`delta0')==`nz'+`cre' & colsof(`delta0')==`nz'+`cre' { tempname delta0sym delta0posdef mata: st_numscalar("`delta0sym'",issymmetric(st_matrix("`delta0'"))) if `delta0sym' { mata: st_numscalar("`delta0posdef'",min(symeigenvalues(st_matrix("`delta0'")))) if `delta0posdef'>0 & `delta0posdef'<. matrix `mydelta0'=`delta0' else delta0err } else delta0err } else if ((rowsof(`delta0')==`nz'+`cre' & colsof(`delta0')==1) | (rowsof(`delta0')==1 & colsof(`delta0')==`nz'+`cre')) { tempname delta0minmax mata: st_matrix("`delta0minmax'",minmax(st_matrix("`delta0'"),1)) if `delta0minmax'[1,1]>0 & `delta0minmax'[1,2]<. matrix `mydelta0'=diag(`delta0') else delta0err } else if rowsof(`delta0')==1 & colsof(`delta0')==1 & `delta0'[1,1]>0 & `delta0'[1,1]<. matrix `mydelta0'=`delta0'*I(`nz'+`cre') else delta0err } else { capture confirm scalar `delta0' if !_rc { if `delta0'>0 & `delta0'<. matrix `mydelta0'=`delta0'*I(`nz'+`cre') else delta0err } else delta0err } *estimate tempname Sigmarows Sigmacols mata: mcmclinear_mixed("`y'","`x'","`z'","`levelvar'",`iterate',`seed',`d0',"`mydelta0'",`cfe',`cre',"`wfe'",`usewfe',`awfe',`showiter',`ng',"`Sigmarows'","`Sigmacols'",`usex',`usez') *name the returned estimation results and calculate b and V matrices qui gen double iter=_n-1 if `nx'>0 { forvalues i=1/`nx' { local j : word `i' of `x' local k : permname beta_`j' rename beta`i' `k' } } if `cfe'==1 { local i=`nx'+1 rename beta`i' beta__cons } forvalues g=1/`ng' { if `nz'>0 { forvalues i=1/`nz' { local j : word `i' of `z' local k : permname theta`g'_`j' local l=(`g'-1)*(`nz'+`cre')+`i' rename theta`l' `k' } } if `cre'==1 { local l=(`g'-1)*(`nz'+`cre')+`nz'+1 rename theta`l' theta`g'__cons } } local nsigma=(`nz'+`cre')*(`nz'+`cre'+1)/2 forvalues j=1/`nsigma' { local r=`Sigmarows'[`j',1] local c=`Sigmacols'[`j',1] rename Sigma`j' Sigma_`r'_`c' } order iter *save qui compress qui save `saving', `replace' *restore original data qui use `temp', clear *return ereturn post [`weightfe' `expfe'], depname(`y') esample(`touse') obs(`N') ereturn local cmd "mcmcmixed" ereturn local cmdline mcmcmixed `mycmdline' } end program delta0err di "delta0 must be a positive scalar, an Nz-by-1 or 1-by-Nz vector of positive numbers, or a symmetric Nz-by-Nz positive definite matrix." error 101 end