You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
959 lines
33 KiB
Plaintext
959 lines
33 KiB
Plaintext
10 months ago
|
*! version 2.5.0 2009-10-28 jsl
|
||
|
* - stata 11 update for returns from -mlogit-
|
||
|
|
||
|
capture program drop mlogplot
|
||
|
capture program drop lp_plt
|
||
|
capture program drop getprob
|
||
|
|
||
|
program define mlogplot
|
||
|
version 6.0
|
||
|
tempname tmp b sd bstd sdrhs 01rhs sdi ch0 chu chs _lpstdt _lpplt isdum
|
||
|
* if 1, then auto exit of mlogview
|
||
|
global PE_mlerr = 0
|
||
|
|
||
|
/* 06Apr2006 - trap 0 category
|
||
|
mat `tmp' = e(cat)
|
||
|
local ncat = e(k_cat)
|
||
|
local i = 1
|
||
|
while `i' <= `ncat' {
|
||
|
local v = `tmp'[`i',1]
|
||
|
if `v' <= 0 {
|
||
|
di in r "outcome categories cannot be 0 or negative."
|
||
|
di in r "recode outcome variable to begin at 1."
|
||
|
exit
|
||
|
}
|
||
|
local i = `i' + 1
|
||
|
}
|
||
|
*/
|
||
|
* 18Nov2005
|
||
|
local maxvar = 7
|
||
|
syntax [varlist(default=none)], [/*
|
||
|
*/ ORatio DChange Prob(real 1) packed labels /*
|
||
|
*/ min(real -99999) max(real 99999) /*
|
||
|
*/ matrix Std(string) Vars(string) /*
|
||
|
*/ dcadd(real 0) dcbase(real .1) NTics(real 7) /*
|
||
|
*/ Basecategory(real -1) Note(string) VALues] /*
|
||
|
*/ [saving(string)] [sign]
|
||
|
|
||
|
* create saving option
|
||
|
local gphopen "gph open"
|
||
|
if "`saving'"~="" { local gphopen "gph open, saving(`saving')" }
|
||
|
|
||
|
local varis `varlist'
|
||
|
if "`varis'"=="" & "`matrix'"~="matrix" {
|
||
|
_perhs
|
||
|
local varis "`r(rhsnms)'"
|
||
|
}
|
||
|
if `min'>=`max' {
|
||
|
di in r "the minimum is larger than the maximum"
|
||
|
exit
|
||
|
}
|
||
|
* dcplot=1 if dc plot
|
||
|
local dcplot = 0
|
||
|
if "`dchange'"=="dchange" & "`oratio'"~="oratio" {
|
||
|
local dcplot = 1
|
||
|
local packed packed
|
||
|
}
|
||
|
* mavar depends on whether there is packing
|
||
|
if "`packed'" == "packed" {
|
||
|
local maxvar = 11 /* max # to plot in packed graph */
|
||
|
}
|
||
|
|
||
|
*=> matrix input
|
||
|
|
||
|
if "`matrix'" == "matrix" {
|
||
|
if `prob'~=1 {
|
||
|
di in r "with matrix input the prob " /*
|
||
|
*/ "option does not work."
|
||
|
local prob = 1
|
||
|
}
|
||
|
if "`dchange'" == "dchange" {
|
||
|
if "`oratio'" ~= "oratio" {
|
||
|
di in r "dchange plots are not " /*
|
||
|
*/ "possible with matrix input."
|
||
|
exit
|
||
|
}
|
||
|
di in r "dchange option does not work " /*
|
||
|
*/ "with matrix output. option was ignored."
|
||
|
local dchange ""
|
||
|
}
|
||
|
|
||
|
local depvar "$mnldepnm"
|
||
|
* names of variables to plot
|
||
|
local varis `vars'
|
||
|
* in b, cols are variables, rows are contrasts
|
||
|
mat `b' = mnlbeta
|
||
|
mat `sdrhs' = mnlsd
|
||
|
local nvarp1 = colsof(`b') + 1 /* with constant */
|
||
|
*todo: check if # of bvarnm is same as cols of b
|
||
|
* variables associated with rows of betas
|
||
|
local bvarnm "$mnlname"
|
||
|
*todo: if doesn't exist, make it all 1's
|
||
|
* columns correspond to columns in betas
|
||
|
mat `sd' = mnlsd
|
||
|
* check size of beta and sd's
|
||
|
local n1 = colsof(`b')
|
||
|
local n2 = colsof(`sd')
|
||
|
if `n1'~=`n2' {
|
||
|
di in r "# of columns in mnlbeta and mnlsd must be equal"
|
||
|
exit
|
||
|
}
|
||
|
} /* if matrix */
|
||
|
|
||
|
*=> get information from mlogit
|
||
|
|
||
|
else {
|
||
|
if "`e(cmd)'"!="mlogit" {
|
||
|
di in r "mlogplot must be run after mlogit or with matrix input"
|
||
|
exit
|
||
|
}
|
||
|
local depvar = e(depvar)
|
||
|
version 5
|
||
|
mat `b' = get(_b)
|
||
|
version 6
|
||
|
* 2009-10-28
|
||
|
tempname eV
|
||
|
_get_mlogit_bv `b' `eV'
|
||
|
*mat list `b'
|
||
|
*mat list `eV'
|
||
|
local bvarnm : colnames(`b')
|
||
|
parse "`bvarnm'", parse (" ")
|
||
|
quietly _pesum, dummy
|
||
|
mat `sdrhs' = r(Ssd)
|
||
|
mat `sdrhs' = `sdrhs'[1,2...]
|
||
|
mat `01rhs' = r(Sdummy)
|
||
|
mat `01rhs' = `01rhs'[1,2...]
|
||
|
|
||
|
* 16Nov2005 1.6.8 - get range
|
||
|
tempname rngrhs
|
||
|
mat `rngrhs' = r(Smax) - r(Smin)
|
||
|
mat `rngrhs' = `rngrhs'[1,2...]
|
||
|
*<
|
||
|
local nvarp1 = colsof(`b') /* with constant */
|
||
|
}
|
||
|
local nvar = `nvarp1' - 1 /* excludes constant */
|
||
|
local ncat = rowsof(`b') + 1
|
||
|
local maxnvar = 3*`nvar' /* allows each var plotted 3 times */
|
||
|
/* 0->1, +-1, +-sd */
|
||
|
if `basecategory' > `ncat' {
|
||
|
di in r "specified base category exceeds number of categories"
|
||
|
exit
|
||
|
}
|
||
|
|
||
|
*=> get discrete change coefficints
|
||
|
*
|
||
|
* Note: PE_dc - each variable has 5 rows
|
||
|
* row 1: 0->1 (16Nov2005 1.6.8 not min->max)
|
||
|
* row 2: min->max (16Nov2005 1.6.8 which can be 0->1)
|
||
|
* row 3: -/+ 1
|
||
|
* row 4: -/+ sd
|
||
|
* row 5: not used
|
||
|
* row label is void if coefficient not computed
|
||
|
|
||
|
* 16Nov2005 1.6.8 - discrete change over range
|
||
|
tempname chr
|
||
|
mat `chr' = J(`nvar',`ncat',0)
|
||
|
|
||
|
mat `ch0' = J(`nvar',`ncat',0)
|
||
|
mat `chu' = J(`nvar',`ncat',0)
|
||
|
mat `chs' = J(`nvar',`ncat',0)
|
||
|
if "`dchange'" == "dchange" {
|
||
|
|
||
|
capture local ncol = colsof(PE_dc)
|
||
|
capture local nrow = rowsof(PE_dc)
|
||
|
|
||
|
if "`ncol'"=="" {
|
||
|
di in r "you must run prchange before " /*
|
||
|
*/ "plotting discrete changes"
|
||
|
global PE_mlerr = 1
|
||
|
exit
|
||
|
}
|
||
|
local nr = `nvar'*5
|
||
|
|
||
|
/* TEST:
|
||
|
di "nvar: `nvar'"
|
||
|
di "nvarp1: `nvarp1'"
|
||
|
di "ncat: `ncat'"
|
||
|
di "maxnvar:`maxnvar'"
|
||
|
di "ncol: `ncol'"
|
||
|
di "nrow: `nrow'"
|
||
|
di "nr: `nr'"
|
||
|
END TEST */
|
||
|
|
||
|
* size of PE_dc is wrong; probably old PE_dc hanging around
|
||
|
* 26Nov2006 - or prchange run on only some of the rhs variables
|
||
|
if `ncol'~=`ncat' | `nrow'~=`nr' {
|
||
|
di in r "There is a problem with the discrete change " ///
|
||
|
"coefficients. Rerun " in w "prchange" in r "."
|
||
|
di in r "Note that " in w "prchange" in r " must include " ///
|
||
|
"all variables. For example, for the model "
|
||
|
di in w "mlogit occ white ed exper" in r ", run " ///
|
||
|
in w "prchange" in r ", not " in w "prchange white ed" ///
|
||
|
in r "."
|
||
|
global PE_mlerr = 1
|
||
|
exit
|
||
|
}
|
||
|
local ivar = 1
|
||
|
local r = 1
|
||
|
while `ivar' <= `nvar' {
|
||
|
local c = 1
|
||
|
* loop over outcome categories
|
||
|
while `c' <= `ncat' {
|
||
|
* 16Nov2005 1.6.8 - retrieve dc over range
|
||
|
scalar `tmp' = PE_dc[`r'+1,`c']
|
||
|
mat `chr'[`ivar',`c'] = `tmp'
|
||
|
* 16Nov2005 1.6.8 retrieve dc from 0 to 1 (same as dc over range)
|
||
|
scalar `tmp' = PE_dc[`r',`c']
|
||
|
*scalar `tmp' = PE_dc[`r'+1,`c']
|
||
|
mat `ch0'[`ivar',`c'] = `tmp'
|
||
|
* -/+ 1
|
||
|
scalar `tmp' = PE_dc[`r'+2,`c']
|
||
|
mat `chu'[`ivar',`c'] = `tmp'
|
||
|
* -/+ sd
|
||
|
scalar `tmp' = PE_dc[`r'+3,`c']
|
||
|
mat `chs'[`ivar',`c'] = `tmp'
|
||
|
local c = `c' + 1
|
||
|
}
|
||
|
local ivar = `ivar' + 1
|
||
|
local r = `r' + 5
|
||
|
}
|
||
|
} /* if dchange */
|
||
|
|
||
|
*=> parse variables to plot and check if dummy variable
|
||
|
mat `_lpplt' = J(`maxnvar',1,0) /* 1 if plot this coef */
|
||
|
mat `isdum' = J(`maxnvar',1,0) /* 1 if dummy variable */
|
||
|
parse "`varis'",parse(" ") /* varis==variables to be plot */
|
||
|
local ntoplot = 0
|
||
|
while "`1'"~="" {
|
||
|
if `ntoplot' >= `maxvar' {
|
||
|
di in r "only `maxvar' variables can be " /*
|
||
|
*/ "plotted in one graph"
|
||
|
exit
|
||
|
}
|
||
|
* check selected name is in beta matrix
|
||
|
local i 1
|
||
|
local okvarn = 0
|
||
|
while `i' <= `nvar' {
|
||
|
* bvarnm contains names from beta matrix
|
||
|
local vnm : word `i' of `bvarnm'
|
||
|
if "`1'"=="`vnm'" { local okvarn = `i' }
|
||
|
local i = `i' + 1
|
||
|
}
|
||
|
if `okvarn'==0 {
|
||
|
di in red "`1' was not a variable in mlogit"
|
||
|
exit
|
||
|
}
|
||
|
local ntoplot = `ntoplot' + 1
|
||
|
if "`matrix'" ~= "matrix" {
|
||
|
mat `isdum'[`ntoplot',1] = `01rhs'[1,`okvarn']
|
||
|
}
|
||
|
* plot variables in this order
|
||
|
mat `_lpplt'[`ntoplot',1] = `okvarn'
|
||
|
macro shift
|
||
|
}
|
||
|
|
||
|
*=> parse standardization type for each variable
|
||
|
|
||
|
mat `_lpstdt' = J(`maxnvar',1,0) /* Plot: 1=unstd; 3=std; 2=0/1 */
|
||
|
local i 1
|
||
|
local nstd = length("`std'")
|
||
|
while `i' <= `nstd' {
|
||
|
local stdi = substr("`std'",`i',1)
|
||
|
|
||
|
* 16Nov2005 1.6.8 - allow r as an option for how to plot variable
|
||
|
if "`stdi'"~="r" & "`stdi'"~="s" & "`stdi'"~="u" & "`stdi'"~="0" {
|
||
|
di in r "std() options must be s, r, u or 0"
|
||
|
* if "`stdi'"~="s" & "`stdi'"~="u" & "`stdi'"~="0" {
|
||
|
* di in r "std() options must be s, u or 0"
|
||
|
exit
|
||
|
}
|
||
|
mat `_lpstdt'[`i',1] = 1 /* unstd */
|
||
|
if "`stdi'" == "s" {
|
||
|
mat `_lpstdt'[`i',1] = 3 /* std */
|
||
|
}
|
||
|
|
||
|
* 16Nov2005 1.6.8 - if range, type 4 coefficients
|
||
|
if "`stdi'" == "r" {
|
||
|
mat `_lpstdt'[`i',1] = 4 /* min max */
|
||
|
}
|
||
|
|
||
|
if "`stdi'" == "0" {
|
||
|
mat `_lpstdt'[`i',1] = 2 /* dummy */
|
||
|
if `isdum'[`i',1]~=1 {
|
||
|
di in r "variable specified as std(0) " /*
|
||
|
*/ "is not a binary variable"
|
||
|
exit
|
||
|
}
|
||
|
}
|
||
|
* warning if isdum and not 0
|
||
|
if `isdum'[`i',1]==1 & `_lpstdt'[`i',1]~=2 {
|
||
|
local tmp = `_lpplt'[`i',1]
|
||
|
local vnm : word `tmp' of `bvarnm'
|
||
|
di in r "warning: variable `vnm'" /*
|
||
|
*/ " is binary, but std(0) was not used"
|
||
|
}
|
||
|
local i = `i' + 1
|
||
|
}
|
||
|
if `ntoplot'~=`nstd' {
|
||
|
di in r "# of variables does not match # of " /*
|
||
|
*/ "std() values specified"
|
||
|
exit
|
||
|
}
|
||
|
|
||
|
*=> set up matrices with plot data
|
||
|
|
||
|
tempname _lpbplt _lpbvar _lpbcat _lpboff _lpbtyp _lpbchk _lpbchp
|
||
|
local tmp = `ntoplot' * `ncat' /* # coefs to plot */
|
||
|
matrix `_lpbplt' = J(`tmp',1,0) /* coef to plot */
|
||
|
matrix `_lpbchp' = `_lpbplt' /* values of discrete change */
|
||
|
matrix `_lpboff' = `_lpbplt' /* vertical offset */
|
||
|
matrix `_lpbvar' = `_lpbplt' /* variable number */
|
||
|
matrix `_lpbcat' = `_lpbplt' /* category */
|
||
|
matrix `_lpbtyp' = `_lpbplt' /* type of standardization */
|
||
|
|
||
|
* compute standardized betas
|
||
|
mat `bstd' = `b'
|
||
|
local ivar = 1
|
||
|
while `ivar' < `nvarp1' {
|
||
|
scalar `sdi' = `sdrhs'[1,`ivar']
|
||
|
* loop over categories and fill in border
|
||
|
local icat = 1
|
||
|
while `icat' < `ncat' {
|
||
|
mat `bstd'[`icat',`ivar'] = `b'[`icat',`ivar'] * `sdi'
|
||
|
local icat = `icat' + 1
|
||
|
}
|
||
|
local ivar = `ivar' + 1
|
||
|
}
|
||
|
|
||
|
* 2007-06-29
|
||
|
if "`matrix'" != "matrix" {
|
||
|
* 16Nov2005 1.6.8 - compute beta*range
|
||
|
tempname brng
|
||
|
mat `brng' = `b'
|
||
|
local ivar = 1
|
||
|
while `ivar' < `nvarp1' {
|
||
|
scalar `sdi' = `rngrhs'[1,`ivar']
|
||
|
* loop over categories and fill in border
|
||
|
local icat = 1
|
||
|
while `icat' < `ncat' {
|
||
|
mat `brng'[`icat',`ivar'] = `b'[`icat',`ivar'] * `sdi'
|
||
|
local icat = `icat' + 1
|
||
|
}
|
||
|
local ivar = `ivar' + 1
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
// make range missing since it is not used
|
||
|
tempname brng
|
||
|
mat `brng' = `bstd' * .
|
||
|
} // 2007-06-29
|
||
|
|
||
|
* determine basecategory
|
||
|
if "`matrix'"~="matrix" {
|
||
|
_pecats `e(depvar)'
|
||
|
local catnm "`r(catnms)'"
|
||
|
* 30Mar2005 1.6.6
|
||
|
if "`values'"=="values" {
|
||
|
local catnm "`r(catvals)'"
|
||
|
}
|
||
|
|
||
|
* refnum is value of the reference category for the estiamted betas
|
||
|
* 2007-06-29 stata 10
|
||
|
if c(stata_version) < 10 {
|
||
|
local refnum = e(basecat)
|
||
|
}
|
||
|
else {
|
||
|
local refnum = e(baseout)
|
||
|
}
|
||
|
|
||
|
* 1.7.0 08Apr2006 - fix when refnum is 0
|
||
|
if `refnum'==0 {
|
||
|
local refnum = 1
|
||
|
}
|
||
|
|
||
|
* names of outcome categories in order of matrix
|
||
|
* all but the last correspond to the rows in b
|
||
|
}
|
||
|
|
||
|
if "`matrix'"=="matrix" {
|
||
|
local catnm "$mnlcatnm"
|
||
|
local refnum "`ncat'"
|
||
|
}
|
||
|
|
||
|
*=> stack b coefficients to plot into _lpbplt vector
|
||
|
|
||
|
* determine offset for plot
|
||
|
* baserow has the row in b with beta's for new base category
|
||
|
local baserow = 0
|
||
|
* `basecategory' has the # of the specified base
|
||
|
if `basecategory'~=`refnum' & `basecategory'~=-1 {
|
||
|
local baserow = `basecategory'
|
||
|
if `basecategory' > `refnum' { local baserow = `baserow' - 1 }
|
||
|
}
|
||
|
* loop through variables, decide on std and unstd to plot
|
||
|
local iloc = 1
|
||
|
local ivar = 1
|
||
|
while `ivar' <= `ntoplot' {
|
||
|
local icat = 1
|
||
|
local varnum = `_lpplt'[`ivar',1]
|
||
|
* find b values for changing basecategory
|
||
|
local bbase = 0
|
||
|
local bbstd = 0
|
||
|
* 16Nov2005 1.6.8
|
||
|
local bbrng = 0
|
||
|
|
||
|
if `baserow' ~= 0 {
|
||
|
local bbase = `b'[`baserow',`varnum']
|
||
|
local bbstd = `bstd'[`baserow',`varnum']
|
||
|
* 16Nov2005 1.6.8
|
||
|
local bbrng = `brng'[`baserow',`varnum']
|
||
|
}
|
||
|
* compute _lpbplt
|
||
|
while `icat' <= `ncat' {
|
||
|
if `icat' < `ncat' {
|
||
|
matrix `_lpbplt'[`iloc',1] = `b'[`icat',`varnum'] - `bbase'
|
||
|
}
|
||
|
else {
|
||
|
matrix `_lpbplt'[`iloc',1] = 0 - `bbase'/* ref category */
|
||
|
}
|
||
|
matrix `_lpbtyp'[`iloc',1] = 1
|
||
|
matrix `_lpbchp'[`iloc',1] = `chu'[`varnum',`icat']
|
||
|
if `_lpstdt'[`ivar',1] == 2 {
|
||
|
matrix `_lpbtyp'[`iloc',1] = 2
|
||
|
matrix `_lpbchp'[`iloc',1] = `ch0'[`varnum',`icat']
|
||
|
}
|
||
|
if `_lpstdt'[`ivar',1] == 3 {
|
||
|
if `icat' < `ncat' {
|
||
|
matrix `_lpbplt'[`iloc',1] = /*
|
||
|
*/ `bstd'[`icat',`varnum'] - `bbstd'
|
||
|
}
|
||
|
else {
|
||
|
matrix `_lpbplt'[`iloc',1] = /*
|
||
|
*/ 0 - `bbstd' /* reference category */
|
||
|
}
|
||
|
matrix `_lpbtyp'[`iloc',1] = 3
|
||
|
matrix `_lpbchp'[`iloc',1] = `chs'[`varnum',`icat']
|
||
|
}
|
||
|
|
||
|
* 16Nov2005 1.6.8 - coefficients when change over range
|
||
|
if `_lpstdt'[`ivar',1] == 4 {
|
||
|
if `icat' < `ncat' {
|
||
|
matrix `_lpbplt'[`iloc',1] = /*
|
||
|
*/ `brng'[`icat',`varnum'] - `bbrng'
|
||
|
}
|
||
|
else {
|
||
|
matrix `_lpbplt'[`iloc',1] = /*
|
||
|
*/ 0 - `bbrng' /* reference category */
|
||
|
}
|
||
|
matrix `_lpbtyp'[`iloc',1] = 4
|
||
|
matrix `_lpbchp'[`iloc',1] = `chr'[`varnum',`icat']
|
||
|
}
|
||
|
|
||
|
* _lpbplt now has coefficients to be plotted
|
||
|
matrix `_lpbvar'[`iloc',1] = `ivar' /* var# for given coef */
|
||
|
matrix `_lpbcat'[`iloc',1] = `icat' /* cat# for tiven coef */
|
||
|
local iloc = `iloc' + 1
|
||
|
local icat = `icat' + 1
|
||
|
}
|
||
|
local ivar = `ivar' + 1
|
||
|
}
|
||
|
|
||
|
if `dcplot' == 1 { /* dcplot , so plot _lpbchp */
|
||
|
matrix `_lpbplt' = `_lpbchp'
|
||
|
}
|
||
|
|
||
|
*=> determine offsets for letters
|
||
|
|
||
|
* algorithm is use offsets of 0,1,2,0,1,2 as coefficients are ordered
|
||
|
* from smallest to largerst. The code is messy, but works...
|
||
|
|
||
|
* if packed, use 0's already in _lpboff
|
||
|
if "`packed'" ~= "packed" {
|
||
|
local iloc = 1
|
||
|
local ivar = 1
|
||
|
while `ivar' <= `ntoplot' {
|
||
|
local varnum = `_lpplt'[`ivar',1]
|
||
|
* grab coefficients for given variable in _lpbplt
|
||
|
local istrt = ((`ivar'-1)*`ncat') + 1
|
||
|
local iend = `istrt' + `ncat' - 1
|
||
|
matrix `_lpbchk' = `_lpbplt'[`istrt'..`iend',1]
|
||
|
local icat = 1
|
||
|
while `icat' <= `ncat' {
|
||
|
local icat2 = 1
|
||
|
local minn = 99999999
|
||
|
* find smallest coef that hasn't been used
|
||
|
while `icat2' <= `ncat' {
|
||
|
if `_lpbchk'[`icat2',1] < `minn' {
|
||
|
local minn = `_lpbchk'[`icat2',1]
|
||
|
local minloc = `icat2'
|
||
|
}
|
||
|
local icat2 = `icat2' + 1
|
||
|
}
|
||
|
* this is current smallest
|
||
|
local updown = mod(`icat'+2,3)
|
||
|
* change to big values so won't select again
|
||
|
mat `_lpbchk'[`minloc',1] = 99999999
|
||
|
local minn = 99999999
|
||
|
* this is the location in the stored variables
|
||
|
local ichng = `istrt' + `minloc' - 1
|
||
|
mat `_lpboff'[`ichng',1] = `updown'
|
||
|
local iloc = `iloc' + 1
|
||
|
local icat = `icat' + 1
|
||
|
}
|
||
|
local ivar = `ivar' + 1
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*=> create variables from the matrices
|
||
|
|
||
|
mat colnames `_lpbplt' = _lpbplt
|
||
|
mat colnames `_lpbvar' = _lpbvar
|
||
|
mat colnames `_lpbcat' = _lpbcat
|
||
|
mat colnames `_lpboff' = _lpboff
|
||
|
mat colnames `_lpbtyp' = _lpbtyp
|
||
|
mat colnames `_lpbchp' = _lpbchp
|
||
|
mat colnames `_lpplt' = _lpplt
|
||
|
mat colnames `_lpstdt' = _lpstdt
|
||
|
|
||
|
svmat `_lpbplt', names(col)
|
||
|
svmat `_lpbvar', names(col)
|
||
|
svmat `_lpbcat', names(col)
|
||
|
svmat `_lpboff', names(col)
|
||
|
svmat `_lpbtyp', names(col)
|
||
|
svmat `_lpbchp', names(col)
|
||
|
svmat `_lpplt', names(col)
|
||
|
svmat `_lpstdt', names(col)
|
||
|
|
||
|
*=> generate variable with first letter of category names
|
||
|
|
||
|
if "`matrix'"~="matrix" {
|
||
|
local ltr : word `refnum' of `catnm'
|
||
|
local ltr = upper(substr("`ltr'",1,1))
|
||
|
quietly generate str1 _lpbltr = "`ltr'"
|
||
|
local icat = 1
|
||
|
while `icat' <= `ncat' {
|
||
|
if `icat'==`refnum' {
|
||
|
local refnm: word `ncat' of `catnm'
|
||
|
if `baserow'~=0 {
|
||
|
local refnm: word `baserow' of `catnm'
|
||
|
}
|
||
|
}
|
||
|
if `icat'!=`refnum' {
|
||
|
local nm: word `icat' of `catnm'
|
||
|
local ltr = upper(substr("`nm'",1,1))
|
||
|
quietly replace _lpbltr = "`ltr'" if _lpbcat == `icat'
|
||
|
}
|
||
|
local icat = `icat' + 1
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if "`matrix'"=="matrix" {
|
||
|
* this is the reference category in the betas
|
||
|
local ltr : word `ncat' of `catnm'
|
||
|
local ltr = upper(substr("`ltr'",1,1))
|
||
|
quietly generate str1 _lpbltr = "`ltr'"
|
||
|
* get letter for reference category
|
||
|
local baserow = `basecategory'
|
||
|
if `baserow' == -1 { local baserow = `ncat' }
|
||
|
local refnm : word `baserow' of `catnm'
|
||
|
* place correct letters to plot
|
||
|
local icat = 1
|
||
|
while `icat' <= `ncat' {
|
||
|
if `icat'!=`refnum' {
|
||
|
local nm: word `icat' of `catnm'
|
||
|
local ltr = upper(substr("`nm'",1,1))
|
||
|
quietly replace _lpbltr = "`ltr'" if _lpbcat == `icat'
|
||
|
}
|
||
|
local icat = `icat' + 1
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*=> data to pass to plot program
|
||
|
|
||
|
global S_1 = `dcplot'
|
||
|
global S_2 = `min'
|
||
|
global S_3 = `max'
|
||
|
global S_4 "`packed'"
|
||
|
global S_5 = `ntoplot'
|
||
|
global S_6 = `dcadd'
|
||
|
global S_7 = `dcbase'
|
||
|
global S_8 = `ncat'
|
||
|
global S_9 "`labels'"
|
||
|
global S_10 "`dchange'"
|
||
|
global S_11 "`bvarnm'"
|
||
|
global S_12 = `prob'
|
||
|
global S_13 "`refnm'"
|
||
|
global S_14 = `ntics'
|
||
|
global S_15 "`note'"
|
||
|
global S_16 "`depvar'"
|
||
|
global S_17 "`gphopen'"
|
||
|
* 16Nov2005 sign
|
||
|
global S_18 = 0
|
||
|
if "`sign'"=="sign" {
|
||
|
global S_18 = 1
|
||
|
}
|
||
|
lp_plt
|
||
|
capture drop _lpbplt-_lprowb
|
||
|
end
|
||
|
|
||
|
program define lp_plt
|
||
|
* decode information from calling program
|
||
|
local dcplot = $S_1
|
||
|
local min = $S_2
|
||
|
local max = $S_3
|
||
|
local packed "$S_4"
|
||
|
local ntoplot = $S_5
|
||
|
local dcadd = $S_6
|
||
|
local dcbase = $S_7
|
||
|
local ncat = $S_8
|
||
|
local labels "$S_9"
|
||
|
local dchange "$S_10"
|
||
|
local bvarnm "$S_11"
|
||
|
local prob = $S_12
|
||
|
local refnm "$S_13"
|
||
|
local ntics = $S_14
|
||
|
local note "$S_15"
|
||
|
local depvar "$S_16"
|
||
|
local gphopen "$S_17"
|
||
|
* 16Nov2005 sign
|
||
|
local addsign = $S_18
|
||
|
|
||
|
* coordinate used:
|
||
|
*
|
||
|
* (0,0) (0,cstrt) (0,cend)
|
||
|
*
|
||
|
* (rhead,cstrt) data (rhead,cend)
|
||
|
*
|
||
|
* (rhead+rvar,cstrt) (rhead+rvar,cend)
|
||
|
*
|
||
|
local cstrt = 10000 /* first column in plot space */
|
||
|
local cborder = 1000 /* border at ends of plot space */
|
||
|
local cend = 31500 /* right most column of plot space */
|
||
|
local crange = `cend' - `cstrt' - (2*`cborder')
|
||
|
local cname = `cstrt' - 700 /* name of variable ends here */
|
||
|
*local rhead = 2000 /* header space for factor change scale */
|
||
|
local rhead = 1800 /* header space for factor change scale */
|
||
|
if `dcplot'==1 { local rhead = 1000 }
|
||
|
if "`note'"~="" {
|
||
|
local rhead = `rhead' + 1000
|
||
|
}
|
||
|
|
||
|
* rows per variable in plot space
|
||
|
* local rvar = 3600 /* maxvar = 5 */
|
||
|
* local rvar = 3200 /* maxvar = 6 */
|
||
|
local rvar = 2800 /* maxvar = 7 */
|
||
|
|
||
|
if "`packed'" == "packed" { local rvar = 1700 }
|
||
|
|
||
|
local rnmoff = 1000 - `rvar' /* vert offset for listing name */
|
||
|
|
||
|
* vert offset within horizontal lines (larger adds vertical compression
|
||
|
local rltoff = 800
|
||
|
|
||
|
* rescale to metric used in columns of plot and find 0 location
|
||
|
quietly sum _lpbplt /* get min and max of coefficients being plotted */
|
||
|
local minb = _result(5)
|
||
|
if `min'~=-99999 & `min'<`minb' { local minb = `min' }
|
||
|
local maxb = _result(6)
|
||
|
if `max'~=99999 & `max'>`maxb' { local maxb = `max' }
|
||
|
local rng = `maxb' - `minb'
|
||
|
* change range to [0-1]
|
||
|
quietly generate _lpcolb = (_lpbplt - `minb')/`rng'
|
||
|
local c0 = (0 - `minb')/`rng'
|
||
|
* min and max column for plotting area
|
||
|
local minn = `cstrt' + `cborder'
|
||
|
local maxx = `cend' - `cborder'
|
||
|
local rng = `maxx' - `minn'
|
||
|
quietly replace _lpcolb = (_lpcolb * `rng') + `minn'
|
||
|
local c0 = (`c0' * `rng') + `minn'
|
||
|
|
||
|
* rescale metric for rows in plot
|
||
|
* # of rows to contain letters
|
||
|
local rltr = `rvar' - `rltoff' - `rltoff'
|
||
|
if "`packed'" ~= "packed" {
|
||
|
quietly sum _lpboff
|
||
|
local minn = _result(5)
|
||
|
local maxx = _result(6)
|
||
|
local rng = `maxx' - `minn'
|
||
|
* change to range of 0--1
|
||
|
quietly generate _lprowb = (_lpboff - `minn')/`rng'
|
||
|
* expand to range of rltr
|
||
|
quietly replace _lprowb = _lprowb * `rltr' /* offsets as # of rows */
|
||
|
* determine row position
|
||
|
#delimit ;
|
||
|
quietly replace _lprowb = _lprowb
|
||
|
+ `rhead' /* skip over header */
|
||
|
+ ((_lpbvar-1)*`rvar') /* space over prior variables */
|
||
|
+ `rltoff' /* space before letters begin */
|
||
|
;
|
||
|
#delimit cr
|
||
|
quietly sum _lprowb
|
||
|
}
|
||
|
else if "`packed'" == "packed" {
|
||
|
local rltoff = 925 /* vert offset top & bot for letters */
|
||
|
* determine row position
|
||
|
#delimit ;
|
||
|
quietly generate _lprowb = `rhead' /* skip over header */
|
||
|
+ ((_lpbvar-1)*`rvar') /* space over prior variables */
|
||
|
+ `rltoff' /* space before letters begin */
|
||
|
;
|
||
|
#delimit cr
|
||
|
}
|
||
|
|
||
|
`gphopen'
|
||
|
gph font 600 300
|
||
|
if "`note'"~="" {
|
||
|
local tmp = `cstrt' - 400
|
||
|
gph text 480 `tmp' 0 -1 `note'
|
||
|
}
|
||
|
local rloc = `rhead' - 200
|
||
|
* axis at top of graph
|
||
|
gph line `rloc' `cstrt' `rloc' `cend'
|
||
|
* add labels at top and bottom
|
||
|
gph font 500 250
|
||
|
local rloc = `rhead' - 1400
|
||
|
if `dcplot' == 0 {
|
||
|
local ltr "`refnm'"
|
||
|
* move top label down a smidge
|
||
|
local rloctmp = `rloc' + 250
|
||
|
gph text `rloctmp' `cstrt' 0 -1 /*
|
||
|
*/ Factor Change Scale Relative to Category `ltr'
|
||
|
local rloc = `rhead' + (`ntoplot'*`rvar') + 1200
|
||
|
local tmp ""
|
||
|
* if "`depvar'" ~= "" { local tmp " of `depvar'" }
|
||
|
local ltr "`refnm' `tmp'"
|
||
|
gph text `rloc' `cstrt' 0 -1 /*
|
||
|
*/ Logit Coefficient Scale Relative to Category `ltr'
|
||
|
}
|
||
|
if `dcplot' == 1 {
|
||
|
local rloc = `rhead' + (`ntoplot'*`rvar') + 1200
|
||
|
*! version 1.6.5 2/24/2003 - correct typo in graph
|
||
|
local tmp "Change in Predicted Probability for $S_16"
|
||
|
gph text `rloc' `cstrt' 0 -1 `tmp'
|
||
|
}
|
||
|
* add tic marks
|
||
|
local nper = (`maxb' - `minb')/(`ntics' - 1)
|
||
|
local itic = 1
|
||
|
local minn = `cstrt' + `cborder'
|
||
|
local maxx = `cend' - `cborder'
|
||
|
local cper = (`maxx' - `minn')/(`ntics' - 1)
|
||
|
while `itic' <= `ntics' {
|
||
|
local ticval : display round(exp(`minb' + ((`itic'-1)*`nper')),.01)
|
||
|
local cval = `minn' + ((`itic'-1)*`cper')
|
||
|
local rloc = `rhead' - 600
|
||
|
* write tic value at top
|
||
|
local rloctmp = `rloc' + 200 /* move it down a smidge */
|
||
|
if `dcplot' ==0 { gph text `rloctmp' `cval' 0 0 `ticval' }
|
||
|
* add tic marks
|
||
|
local rlst = `rhead' - 200
|
||
|
local rlend = `rlst' + 150
|
||
|
gph line `rlst' `cval' `rlend' `cval'
|
||
|
local rlst = `rhead' + (`ntoplot'*`rvar') - 200
|
||
|
local rlend = `rlst' - 150
|
||
|
gph line `rlst' `cval' `rlend' `cval'
|
||
|
local ticval : display round(`minb' + ((`itic'-1)*`nper'),.01)
|
||
|
local itic = `itic' + 1
|
||
|
local rloc = `rhead' + (`ntoplot'*`rvar') + 400
|
||
|
gph text `rloc' `cval' 0 0 `ticval'
|
||
|
}
|
||
|
local rloc = `rhead' + (`ntoplot'*`rvar') - 200
|
||
|
gph line `rloc' `cstrt' `rloc' `cend'
|
||
|
if `dcplot' == 1 {
|
||
|
local rt = `rhead' - 200
|
||
|
gph line `rt' `c0' `rloc' `c0'
|
||
|
}
|
||
|
|
||
|
* plot letters
|
||
|
local i 0
|
||
|
local ivar 1
|
||
|
local dcbase = sqrt(`dcbase')
|
||
|
while `ivar' <= `ntoplot' { /* loop over variables */
|
||
|
local icat 1
|
||
|
while `icat' <= `ncat' { /* loop over categories within vars */
|
||
|
local i = `i' + 1
|
||
|
* get point to plot
|
||
|
local r = _lprowb[`i']
|
||
|
local c = _lpcolb[`i']
|
||
|
local l = _lpbltr[`i']
|
||
|
local siz 1
|
||
|
if "`dchange'" == "dchange" & `dcplot' == 0 {
|
||
|
local siz = sqrt(`dcadd'+abs(_lpbchp[`i']))/`dcbase'
|
||
|
}
|
||
|
local fr = `siz'*700
|
||
|
local fc = `siz'*350
|
||
|
gph font `fr' `fc'
|
||
|
|
||
|
* 16Nov2005 option sign
|
||
|
if _lpbchp[`i']<0 & `addsign'==1 {
|
||
|
gph text `r' `c' 0 0 _
|
||
|
* local l "-`l'"
|
||
|
}
|
||
|
|
||
|
gph text `r' `c' 0 0 `l'
|
||
|
local icat = `icat' + 1
|
||
|
}
|
||
|
local ivar = `ivar' + 1
|
||
|
}
|
||
|
|
||
|
* add names and dividing lines
|
||
|
local ivar = 1
|
||
|
while `ivar' <= `ntoplot' {
|
||
|
* name of variable
|
||
|
local varnum = _lpplt[`ivar']
|
||
|
if `dcplot' == 0 & `prob'~= 1 {
|
||
|
* get prob values
|
||
|
global S_1 = `varnum' /* variable number */
|
||
|
global S_2 = `ncat'
|
||
|
getprob
|
||
|
local cat1 2
|
||
|
while `cat1' <= `ncat' {
|
||
|
* location in data set of coordinates for this coef
|
||
|
local loc1 = ((`ivar'-1)*`ncat')+`cat1'
|
||
|
local r1 = _lprowb[`loc1']
|
||
|
local c1 = _lpcolb[`loc1']
|
||
|
local cat2 1
|
||
|
while `cat2' < `cat1' {
|
||
|
local loc2 = ((`ivar'-1)*`ncat')+`cat2'
|
||
|
local r2 = _lprowb[`loc2']
|
||
|
local c2 = _lpcolb[`loc2']
|
||
|
local p = mlplt_p[`cat1',`cat2']
|
||
|
if `p' > `prob' { gph line `r1' `c1' `r2' `c2' }
|
||
|
local cat2 = `cat2' + 1
|
||
|
} /* `cat2' < `cat1' */
|
||
|
local cat1 = `cat1' + 1
|
||
|
} /* `cat1' < `ncat' */
|
||
|
} /* if get prob */
|
||
|
local vname: word `varnum' of `bvarnm'
|
||
|
if "`labels'" == "labels" & "`matrix'"~="matrix" {
|
||
|
local vname2 : variable label `vname'
|
||
|
if "`vname2'"!="" { local vname "`vname2'"}
|
||
|
}
|
||
|
local rloc = `rhead' + `rnmoff' + (`ivar'*`rvar')
|
||
|
gph font 700 350
|
||
|
local _lpstdt = _lpstdt[`ivar']
|
||
|
if "`packed'" == "packed" {
|
||
|
if `_lpstdt' == 3 {
|
||
|
gph text `rloc' `cname' 0 1 `vname'-std
|
||
|
}
|
||
|
else if `_lpstdt' == 2 {
|
||
|
gph text `rloc' `cname' 0 1 `vname'-0/1
|
||
|
}
|
||
|
else if `_lpstdt' == 1 {
|
||
|
gph text `rloc' `cname' 0 1 `vname'
|
||
|
}
|
||
|
* 16Nov2005 1.6.8 - label for dc over range
|
||
|
else if `_lpstdt' == 4 {
|
||
|
gph text `rloc' `cname' 0 1 `vname'-range
|
||
|
}
|
||
|
}
|
||
|
if "`packed'" ~= "packed" {
|
||
|
gph text `rloc' `cname' 0 1 `vname'
|
||
|
gph font 400 200
|
||
|
local rloc = `rhead' + `rnmoff' + (`ivar'*`rvar') + 900
|
||
|
if `_lpstdt' == 1 {
|
||
|
gph text `rloc' `cname' 0 1 UnStd Coef
|
||
|
}
|
||
|
if `_lpstdt' == 2 {
|
||
|
gph text `rloc' `cname' 0 1 0/1
|
||
|
}
|
||
|
if `_lpstdt' == 3 {
|
||
|
gph text `rloc' `cname' 0 1 Std Coef
|
||
|
}
|
||
|
* 16Nov2005 1.6.8 - label for or over range
|
||
|
else if `_lpstdt' == 4 {
|
||
|
gph text `rloc' `cname' 0 1 Range Coef
|
||
|
}
|
||
|
}
|
||
|
* dividing line
|
||
|
if `ivar' != 1 {
|
||
|
local rloc = `rhead' + ((`ivar'-1)*`rvar') - 200
|
||
|
gph line `rloc' `cstrt' `rloc' `cend'
|
||
|
}
|
||
|
local ivar = `ivar' + 1
|
||
|
}
|
||
|
gph close
|
||
|
end
|
||
|
|
||
|
program define getprob
|
||
|
* get the prob values for all contrasts
|
||
|
version 5.0
|
||
|
tempname b v b1 b2 b12 se z p
|
||
|
local ivar = $S_1
|
||
|
local ncat = $S_2
|
||
|
matrix `b' = get(_b)
|
||
|
local nvars = colsof(`b')
|
||
|
mat `v' = get(VCE)
|
||
|
* 2009-10-28 - fix for stata 11 returns
|
||
|
nobreak {
|
||
|
_get_mlogit_bv `b' `v'
|
||
|
local nvars = colsof(`b')
|
||
|
}
|
||
|
/* TEST
|
||
|
di "nvars: `nvars'"
|
||
|
di "ncat: `ncat'"
|
||
|
di "v with fix"
|
||
|
mat list `v'
|
||
|
di "b with fix"
|
||
|
mat list `b'
|
||
|
END TEST */
|
||
|
matrix mlplt_p = J(`ncat',`ncat',1)
|
||
|
* loop through all pairs of categories
|
||
|
local cat1 1
|
||
|
local cat2 1
|
||
|
while `cat1' <= `ncat' {
|
||
|
while `cat2' <= `cat1' {
|
||
|
if `cat1'!=`cat2' {
|
||
|
* 1st element of contrast is not ref cat
|
||
|
if `cat1'!=`ncat' {
|
||
|
if `cat2'==`ncat' { scalar `b2' = 0 }
|
||
|
else { scalar `b2' = `b'[`cat2',`ivar'] }
|
||
|
scalar `b1' = `b'[`cat1',`ivar']
|
||
|
scalar `b12' = `b1'-`b2'
|
||
|
local loc2 = ((`cat2'-1)*`nvars')+`ivar'
|
||
|
if `cat2'==`ncat' {
|
||
|
scalar `se' = sqrt(`v'[`loc1',`loc1'])
|
||
|
}
|
||
|
else {
|
||
|
local loc1 = ((`cat1'-1)*`nvars')+`ivar'
|
||
|
scalar `se' = sqrt(`v'[`loc1',`loc1'] + /*
|
||
|
*/ `v'[`loc2',`loc2'] - 2*`v'[`loc1',`loc2'])
|
||
|
}
|
||
|
} /* `cat1'!=`ncat' */
|
||
|
* first element of contrast is reference category
|
||
|
if `cat1'==`ncat' {
|
||
|
if `cat2'==`ncat' { scalar `b2' = 0 }
|
||
|
else { scalar `b2' = `b'[`cat2',`ivar'] }
|
||
|
scalar `b1' = 0 /*`b'[`cat1',`ivar']*/
|
||
|
scalar `b12' = `b1'-`b2'
|
||
|
local loc2 = ((`cat2'-1)*`nvars')+`ivar'
|
||
|
scalar `se' = sqrt(`v'[`loc2',`loc2'])
|
||
|
}
|
||
|
scalar `se' = 1/`se'
|
||
|
scalar `z' = `se'*`b12'
|
||
|
scalar `p' = 2*normprob(-abs(`z'))
|
||
|
matrix mlplt_p[`cat1',`cat2'] = `p'
|
||
|
matrix mlplt_p[`cat2',`cat1'] = `p'
|
||
|
} /* if `cat1'!=`cat2' */
|
||
|
local cat2 = `cat2' + 1
|
||
|
} /* while `cat2' <= `ncat' */
|
||
|
local cat2 1
|
||
|
local cat1 = `cat1' + 1
|
||
|
} /* cat1 */
|
||
|
|
||
|
end
|
||
|
exit
|
||
|
|
||
|
* version 1.6.4 3/22/2001
|
||
|
* version 1.6.5 2/24/2003 - correct typo in graph
|
||
|
* version 1.6.6 30Mar2005 - add values option
|
||
|
* version 1.6.7 13Apr2005
|
||
|
* version 1.6.8 allow plots for change over range 16Nov2005
|
||
|
* add: option sign: underline negative discrete change
|
||
|
* option r : for range
|
||
|
* version 1.6.9 error if outcome cat <= 0
|
||
|
* version 1.7.0 08Apr2006 fixed when basecategory is 0!
|
||
|
* version 1.7.1 26Nov2006
|
||
|
* improve error message when prchange is a problem.
|
||
|
* version 1.7.2 29Jun2007 // fix range problem if data is a matrix
|
||
|
* version 1.7.3 29Jun2007 // stata 10 revisions
|