*! version 1.0.3 31jan1996 program define dmlogit2 version 5.0 local options "Level(integer $S_level) noDISPat" if substr("`1'",1,1)=="," | "`*'"=="" { if "$S_E_cmd"!="dmlogit2" { error 301 } parse "`*'" } else { local varlist "req ex" local weight "fweight aweight" local if "opt" local in "opt" local options "`options' AT(string) LOG noConstant *" parse "`*'" if "`log'"=="" { local log "quietly" } else local log tempname b V x tempvar doit mark `doit' [`weight'`exp'] `if' `in' markout `doit' `varlist' parse "`varlist'", parse(" ") local y "`1'" /* Run mlogit. */ `log' mlogit `varlist' [`weight'`exp'] if `doit', /* */ `options' `constan' mat `b' = get(_b) mat `V' = get(VCE) local nobs = _result(1) local ll = _result(2) local pr2 = _result(7) /* Use colnames for indepvars since some may have been dropped. */ local colname : colnames(`b') parse "`colname'", parse(" ") local dim = colsof(`b') if "``dim''"=="_cons" { local `dim' /* erase "_cons" */ } /* Get x. */ if "`at'"!="" { local at "at(`at')" } dlog_at `doit' `*' [`weight'`exp'], x(`x') `at' `constan' /* Compute dP/dx and its covariance. */ dPdx `x' `b' `V' /* new b and V returned */ local sing "$S_1" /* Post results. */ mat post `b' `V', depn(`y') obs(`nobs') /* Compute test of indepvars = 0. */ if "`constan'"=="" & "`*'"!="" & "`sing'"=="" { qui test `*' global S_E_mdf = _result(3) global S_E_chi2 = _result(6) } else if "`sing'"!="" { global S_E_mdf "." global S_E_chi2 "." } matrix S_E_x = `x' global S_E_nobs "`nobs'" global S_E_ll "`ll'" global S_E_pr2 "`pr2'" global S_E_depv "`y'" global S_E_cmd "dmlogit2" } /* Display results. */ #delimit ; di _n in gr "Marginal effects from multinomial regression" _col(54) "Number of obs = " in ye %7.0g $S_E_nobs ; if "$S_E_mdf"!="" { ; di _col(54) in gr "chi2(" in ye $S_E_mdf in gr ")" _col(70) "= " in ye %7.2f $S_E_chi2 _n _col(54) in gr "Prob > chi2 = " in ye %7.4f chiprob($S_E_mdf, $S_E_chi2) _c ; } ; di _n in gr "Log Likelihood = " in ye %10.0g $S_E_ll _col(54) in gr "Pseudo R2 = " in ye %7.4f $S_E_pr2 _n ; #delimit cr mat mlout, level(`level') if "`dispat'"=="" { di in gr "Marginal effects evaluated at" mat list S_E_x, noheader format(%9.0g) } end program define dPdx version 4.0 local x "`1'" /* Input: row vector (1 x k) of x values */ local b "`2'" /* Input: beta (m x k) from mlogit */ /* Output: dP/dx marginal effects row vector */ local V "`3'" /* Input: covariance matrix (mk x mk) of beta */ /* Output: covariance of dP/dx */ tempname A P s sum I r D C E local m = rowsof(`b') local k = colsof(`b') mat `A' = `b'*`x'' mat `P' = J(`m',`m',0) scalar `sum' = 1 local i 1 while `i' <= `m' { scalar `s' = exp(`A'[`i',1]) scalar `sum' = `sum' + `s' mat `P'[`i',`i'] = `s' local i = `i' + 1 } scalar `sum' = 1/`sum' mat `P' = `sum'*`P' mat `A' = J(`m',`m',1) mat `A' = `A'*`P' mat `A' = `A'*`b' mat `A' = `b' - `A' mat `I' = I(`k') mat `r' = J(1,`m',0) local mk = `m'*`k' mat `D' = J(`mk',`mk',0) local i 1 while `i' <= `m' { local ki = `k'*(`i'-1) + 1 /* Make new b a row vector. */ mat `C' = `A'[`i',.] scalar `s' = `P'[`i',`i'] mat `C' = `s'*`C' if `i' == 1 { mat `b' = `C' } else mat `b' = `b' , `C' /* Do j = i. */ mat `C' = `A'[`i',.] scalar `s' = 1 - 2*`P'[`i',`i'] mat `C' = `s'*`C' mat `C' = `C''*`x' scalar `s' = 1 - `P'[`i',`i'] mat `E' = `s'*`I' mat `C' = `E' + `C' scalar `s' = `P'[`i',`i'] mat `C' = `s'*`C' mat sub `D'[`ki',`ki'] = `C' /* Do j < i. */ mat `r'[1,`i'] = 1 local j 1 while `j' < `i' { mat `r'[1,`j'] = 1 mat `C' = `r'*`A' mat `C' = `C''*`x' mat `C' = `I' + `C' scalar `s' = -`P'[`i',`i']*`P'[`j',`j'] mat `C' = `s'*`C' local kj = `k'*(`j'-1) + 1 mat sub `D'[`ki',`kj'] = `C' mat sub `D'[`kj',`ki'] = `C' mat `r'[1,`j'] = 0 local j = `j' + 1 } mat `r'[1,`i'] = 0 local i = `i' + 1 } /* If `V' is singular, zero corresponding row of D. */ mat `r' = J(1, `mk', 0) global S_1 /* erase macro */ local i 1 while `i' <= `mk' { if `V'[`i',`i'] == 0 { mat sub `D'[`i',1] = `r' global S_1 "singular" } local i = `i' + 1 } /* Make new V. */ mat `E' = `V' mat `V' = `D'*`V' mat `V' = `V'*`D'' /* Symmetrize V (it may be slightly off due to numerical error). */ mat `D' = `V'' mat `V' = `V' + `D' scalar `s' = 0.5 mat `V' = `s'*`V' /* Label new b and V. We do it in this strange fashion in case equation names contain spaces (which is possible since names can come from value labels). */ mat `r' = `E'[1,.] scalar `s' = 0 mat `r' = `s'*`r' mat `E' = `s'*`E' mat `b' = `b' + `r' mat `V' = `V' + `E' end