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.

1300 lines
49 KiB
Plaintext

*! version 2.5.2 2009-12-11 jsl
* - deal with negative value in ologit for outcome option
* version 2.5.1 2009-12-10 jsl
* - deal with negative value in ologit
capture program drop prchange
program define prchange, rclass
* 1.9.0
local caller = _caller()
version 6
tempname delthlf delt
tempname tobase tobase2 min max mean sd min2 max2 mean2 sd2 marg
tempname margout marg2 margou2
tempname sdx sdxhalf minx maxx lobase hibase x_base xb xb_lo xb_hi mu
tempname p1 p_lo p_hi temp tmp tmp_lo tmp_hi vmarg vchange dchange basepr
tempname baseval basezi // 2006-02-18 for estout
mat def `baseval' = J(1,1,.)
mat def `basezi' = J(1,1,.)
tempname /*deltais*/ predis change // changed 05nov2007 bj
mat def `change' = J(1,1,.)
mat def `predis' = J(1,1,.)
tempname nomtemp
*=> classify each valid type of model
*zt 18Feb2005
local iszt = 0 //
if ("`e(cmd)'"=="ztp" | "`e(cmd)'"=="ztnb") {
local iszt = 1
}
if "`e(cmd)'"=="ztp" { local io = "typical count" }
if "`e(cmd)'"=="ztnb" { local io = "typical count" }
if "`e(cmd)'"=="cloglog" { local io = "typical binary" }
if "`e(cmd)'"=="gologit" { local io = "typical ordered" }
if "`e(cmd)'"=="logistic" { local io = "typical binary" }
if "`e(cmd)'"=="logit" { local io = "typical binary" }
if "`e(cmd)'"=="mlogit" { local io = "typical nomord" }
if "`e(cmd)'"=="mprobit" { local io = "typical nomord" } // 16Feb2008 sl
if "`e(cmd)'"=="nbreg" { local io = "typical count" }
if "`e(cmd)'"=="ologit" { local io = "typical nomord" }
if "`e(cmd)'"=="oprobit" { local io = "typical nomord" }
if "`e(cmd)'"=="slogit" { local io = "typical nomord" }
if "`e(cmd)'"=="poisson" { local io = "typical count" }
if "`e(cmd)'"=="probit" { local io = "typical binary" }
if "`e(cmd)'"=="zinb" { local io = "twoeq count" }
if "`e(cmd)'"=="zip" { local io = "twoeq count" }
if "`io'"=="" {
di
di in y "prchange" in r " does not work for last model estimated."
exit
}
local input : word 1 of `io' /* input routine to _pepred */
local output : word 2 of `io' /* output routine */
*=> get info about variables
_perhs
local nrhs = `r(nrhs)'
local rhsnms "`r(rhsnms)'"
if "`input'"=="twoeq" {
local nrhs2 = `r(nrhs2)'
local rhsnms2 "`r(rhsnms2)'"
}
if "`output'" != "regress" & "`output'" != "tobit" {
_pecats
local ncats = r(numcats)
local catnms8 `r(catnms8)'
local catvals `r(catvals)'
local catnms `r(catnms)'
}
*=> decode input
syntax [varlist(default=none)] [if] [in] /*
*/ [, x(passthru) Rest(passthru) Level(passthru) Delta(real 1) /*
*/ UNCentered Fromto all Outcome(string) noBAse noLAbel Help Brief /*
*/ CONditional ]
*zt 19Feb2005
if `iszt'==1 & "`conditional'"=="conditional" ///
& "`outcome'"=="0" {
di _n in r "conditional probabilities for outcome 0 are undefined."
exit
}
*convert delta() to scalars
sca `delt' = `delta'
sca `delthlf' = `delt'/2
* _pebase handles input and sets base values
_pebase `if' `in', `x' `rest' `choices' `all'
mat `tobase' = r(pebase)
if "`input'"=="twoeq" { mat `tobase2' = r(pebase2) }
* _peife combines `if' with e(sample)==1 if needed
_peife `if', `all'
local if "`r(if)'"
* summary statistics on rhs variables
quietly _pesum `if' `in'
mat `min' = r(Smin)
mat `min' = `min'[1, 2...]
mat `max' = r(Smax)
mat `max' = `max'[1, 2...]
mat `mean' = r(Smean)
mat `mean' = `mean'[1, 2...]
mat `sd' = r(Ssd)
mat `sd' = `sd'[1, 2...]
* 2006-02-18 - base values to be returned for estout
mat `baseval' = `mean' \ `sd' \ `min' \ `max'
mat rownames `baseval' = Mean SD Min "Max"
if "`input'"=="twoeq" {
quietly _pesum `if' `in', two
mat `min2' = r(Smin)
mat `min2' = `min2'[1, 2...]
mat `max2' = r(Smax)
mat `max2' = `max2'[1, 2...]
mat `mean2' = r(Smean)
mat `mean2' = `mean2'[1, 2...]
mat `sd2' = r(Ssd)
mat `sd2' = `sd2'[1, 2...]
* 2006-02-18 - zip & zinb base values to be returned for estout
mat `basezi' = `mean2' \ `sd2' \ `min2' \ `max2'
mat rownames `basezi' = Mean SD Min Max
}
* set values of PE_in, to be modified before sent to _pepred
capture mat drop PE_in
mat PE_in = `tobase'
if "`input'"=="twoeq" {
capture mat drop PE_in2
mat PE_in2 = `tobase2'
}
if "`varlist'" == "" { local varlist "`rhsnms'" }
*=> handle outcome() option
if "`outcome'"!="" {
if "`output'"=="binary" {
di in r "outcome() not allowed for prchange after `e(cmd)'"
exit 198
}
if "`output'"=="nomord" {
local found "no"
* cycle through outcome categories
local i = 1
while `i' <= `ncats' {
local valchk : word `i' of `catvals'
local nmchk : word `i' of `catnms'
* outcome() value to category value
if ("`outcome'"=="`valchk'") | ("`outcome'"=="`nmchk'") {
local found "yes"
local outcmv = "`valchk'"
* 2.5.2
local outcmvnm "`outcmv'"
if `outcome'<0 {
local outcmvnm = abs(`outcmv')
local outcmvnm "_`outcmvnm'"
}
if "`valchk'"!="`nmchk'" { local outcmnm " (`nmchk')" }
local outcome = `i'
local i = `ncats'
}
local i = `i' + 1
}
if "`found'"=="no" {
di in r "`outcome' not category of `e(depvar)'"
exit 198
}
} // output is nomord
if "`output'"=="count" {
confirm integer number `outcome'
if `outcome' < 0 { exit 198 }
local outcmv "`outcome'"
}
}
*=> compute marginal effects (_pemarg requires mat PE_base that was set by _pebase)
* zt 19Feb2005 TO DO
* 1.8.0 _pemarg
_pemarg, caller(`caller') // 1.9.0
local hasmarg = "`r(hasmarg)'"
if "`hasmarg'"=="yes" {
mat `marg' = r(marginal)
if "`output'"=="count" | "`output'"=="binary" {
mat `marg' = `marg'[2, 1...]
}
}
*=> header information
if "`brief'"=="" {
*zt 19Feb2005
if `iszt'==1 {
if "`conditional'"=="" {
local type "Unconditional "
}
else {
local type "Conditional "
}
}
di _n in y "`e(cmd)'" _c
if "`output'"=="count" & "`outcome'"=="" {
di in g ": Changes in `type'Rate for " _c
}
else { di in g ": Changes in `type'Probabilities for " _c}
di in y "`e(depvar)'"
if "`outcome'"!="" {
di in g _new "Outcome: " in y "`outcmv'" in y "`outcmnm'" // 2007-01-07
}
*print value of delta if specified
if `delt'!=1 {
if "`uncentered'"!="" {
di _n in g "(Note: delta = " in y `delt' in g ")"
}
else {
di _n in g "(Note: d = " in y `delt' in g ")"
}
}
}
*=> cycle through all variables in varlist
* varnum = matrix position of rhs variable; -1 if not in count equation
* varnum2 =position in binary matrix of rhs var in ZIP/ZINB; -1 if absent
local i = 1
local i_to : word count `varlist'
while `i' <= `i_to' {
local var : word `i' of `varlist'
local found "no"
local varnum -1
local i2 = 1
local i2_to : word count `rhsnms'
while `i2' <= `i2_to' {
local varchk : word `i2' of `rhsnms'
unab varchk : `varchk', max(1)
if "`var'"=="`varchk'" {
local found "yes"
local varnum = `i2'
local i2 = `i2_to'
}
local i2 = `i2' + 1
} /* while `i2' < `i2_to' */
if "`input'"=="twoeq" {
local i3 = 1
local i3_to : word count `rhsnms2'
local varnum2 -1
while `i3' <= `i3_to' {
local varchk : word `i3' of `rhsnms2'
unab varchk : `varchk', max(1)
if "`var'"=="`varchk'" {
local found "yes"
local varnum2 = `i3'
local i3 = `i3_to'
}
local i3 = `i3' + 1
}
} /* if "`input'"=="twoeq" */
if "`found'"=="no" {
di in r "`var' not rhs variable"
exit 198
}
*=> arrange `marg' matrix for output
if `varnum' != -1 & "`hasmarg'"=="yes" {
if "`output'"=="nomord" | "`output'"=="mlogit" {
mat `margout' = nullmat(`margout') \ `marg'[`varnum', 1...]
}
else {
mat `margout' = nullmat(`margout') , `marg'[1, `varnum']
}
}
*=> PE_in has values of start and end of change variable
* and levels of other variables for all changes considered
if `varnum' != -1 {
* create scalar values for discrete change calculations
sca `sdx' = `sd'[1, `varnum']
sca `sdxhalf' = `sdx' / 2
sca `minx' = `min'[1, `varnum']
sca `maxx' = `max'[1, `varnum']
sca `x_base' = `tobase'[1, `varnum']
* for min --> max
mat `lobase' = `tobase'
mat `lobase'[1, `varnum'] = `minx'
mat PE_in = PE_in \ `lobase'
mat `hibase' = `tobase'
mat `hibase'[1, `varnum'] = `maxx'
mat PE_in = PE_in \ `hibase'
* low and high values for 0 --> 1
mat `lobase' = `tobase'
mat `lobase'[1, `varnum'] = 0
mat PE_in = PE_in \ `lobase'
mat `hibase' = `tobase'
mat `hibase'[1, `varnum'] = 1
mat PE_in = PE_in \ `hibase'
* +/- delta
if "`uncentered'"=="" {
mat `lobase' = `tobase'
mat `lobase'[1, `varnum'] = `x_base'-`delthlf'
mat PE_in = PE_in \ `lobase'
mat `hibase' = `tobase'
mat `hibase'[1, `varnum'] = `x_base'+`delthlf'
mat PE_in = PE_in \ `hibase'
}
else {
mat `lobase' = `tobase'
mat `lobase'[1, `varnum'] = `x_base'
mat PE_in = PE_in \ `lobase'
mat `hibase' = `tobase'
mat `hibase'[1, `varnum'] = `x_base'+`delt'
mat PE_in = PE_in \ `hibase'
}
* for +/- sdx
if "`uncentered'"=="" {
mat `lobase' = `tobase'
mat `lobase'[1, `varnum'] = `x_base'-`sdxhalf'
mat PE_in = PE_in \ `lobase'
mat `hibase' = `tobase'
mat `hibase'[1, `varnum'] = `x_base'+`sdxhalf'
mat PE_in = PE_in \ `hibase'
}
else {
mat `lobase' = `tobase'
mat `lobase'[1, `varnum'] = `x_base'
mat PE_in = PE_in \ `lobase'
mat `hibase' = `tobase'
mat `hibase'[1, `varnum'] = `x_base'+`sdx'
mat PE_in = PE_in \ `hibase'
}
} /* if `varnum' != -1 */
* if rhs variable not in equation, then all PE_in rows == tobase
else {
mat PE_in = nullmat(PE_in) \ `tobase'
mat PE_in = PE_in \ `tobase'
mat PE_in = PE_in \ `tobase'
mat PE_in = PE_in \ `tobase'
mat PE_in = PE_in \ `tobase'
mat PE_in = PE_in \ `tobase'
mat PE_in = PE_in \ `tobase'
mat PE_in = PE_in \ `tobase'
}
* handle PE_in2 for second equation if zip/zinb
if "`input'"=="twoeq" {
if "`varnum2'" != "-1" {
tempname sdx sdxhalf minx maxx
sca `sdx' = `sd2'[1, `varnum2']
sca `sdxhalf' = `sdx' / 2
sca `minx' = `min2'[1, `varnum2']
sca `maxx' = `max2'[1, `varnum2']
tempname lobase hibase x_base
sca `x_base' = `tobase2'[1, `varnum2']
* min --> max
mat `lobase' = `tobase2'
mat `lobase'[1, `varnum2'] = `minx'
mat PE_in2 = PE_in2 \ `lobase'
mat `hibase' = `tobase2'
mat `hibase'[1, `varnum2'] = `maxx'
mat PE_in2 = PE_in2 \ `hibase'
* 0 --> 1
mat `lobase' = `tobase2'
mat `lobase'[1, `varnum2'] = 0
mat PE_in2 = PE_in2 \ `lobase'
mat `hibase' = `tobase2'
mat `hibase'[1, `varnum2'] = 1
mat PE_in2 = PE_in2 \ `hibase'
* +/- delta
if "`uncentered'"=="" {
mat `lobase' = `tobase2'
mat `lobase'[1, `varnum2'] = `x_base'-`delthlf'
mat PE_in2 = PE_in2 \ `lobase'
mat `hibase' = `tobase2'
mat `hibase'[1, `varnum2'] = `x_base'+`delthlf'
mat PE_in2 = PE_in2 \ `hibase'
}
else {
mat `lobase' = `tobase2'
mat `lobase'[1, `varnum2'] = `x_base'
mat PE_in2 = PE_in2 \ `lobase'
mat `hibase' = `tobase2'
mat `hibase'[1, `varnum2'] = `x_base'+`delt'
mat PE_in2 = PE_in2 \ `hibase'
}
* +/- sdx
if "`uncentered'"=="" {
mat `lobase' = `tobase2'
mat `lobase'[1, `varnum2'] = `x_base'-`sdxhalf'
mat PE_in2 = PE_in2 \ `lobase'
mat `hibase' = `tobase2'
mat `hibase'[1, `varnum2'] = `x_base'+`sdxhalf'
mat PE_in2 = PE_in2 \ `hibase'
}
else {
mat `lobase' = `tobase2'
mat `lobase'[1, `varnum2'] = `x_base'
mat PE_in2 = PE_in2 \ `lobase'
mat `hibase' = `tobase2'
mat `hibase'[1, `varnum2'] = `x_base'+`sdx'
mat PE_in2 = PE_in2 \ `hibase'
}
} /* if "`varnum2'" != "-1" */
* if not in inflate equation, PE_in2==tobase2
else {
mat PE_in2 = nullmat(PE_in2) \ `tobase2'
mat PE_in2 = PE_in2 \ `tobase2'
mat PE_in2 = PE_in2 \ `tobase2'
mat PE_in2 = PE_in2 \ `tobase2'
mat PE_in2 = PE_in2 \ `tobase2'
mat PE_in2 = PE_in2 \ `tobase2'
mat PE_in2 = PE_in2 \ `tobase2'
mat PE_in2 = PE_in2 \ `tobase2'
} /* else */
} /* if "`input'"=="twoeq" */
local i = `i' + 1
} /* while `i' <= `i_to' */
*=> _pepred calculates probabilities based on PE_in
_pepred, `level'
local max_i = r(maxcount)
*=> BINARY MODELS
if "`output'"=="binary" {
* predicted probability for all rows of PE_in
mat `p1' = r(p1)
local i = 1
local i_to : word count `varlist'
mat `dchange' = J(`i_to', 4, 0)
local dchcol 1
if "`fromto'"=="fromto" {
mat `dchange' = J(`i_to', 12, 0)
local dchcol 3
}
* cycle though variables
while `i' <= `i_to' {
* calculate discrete change as difference and put in dchange matrix
local anchor = (`i' * 8) - 6
sca `p_lo' = `p1'[`anchor', 1]
sca `p_hi' = `p1'[`anchor'+1, 1]
if "`fromto'"=="fromto" {
mat `dchange'[`i', 1] = `p_lo'
mat `dchange'[`i', 2] = `p_hi'
}
mat `dchange'[`i', 1*`dchcol'] = `p_hi' - `p_lo'
sca `p_lo' = `p1'[`anchor'+2, 1]
sca `p_hi' = `p1'[`anchor'+3, 1]
if "`fromto'"=="fromto" {
mat `dchange'[`i', 4] = `p_lo'
mat `dchange'[`i', 5] = `p_hi'
}
mat `dchange'[`i', 2*`dchcol'] = `p_hi' - `p_lo'
sca `p_lo' = `p1'[`anchor'+4, 1]
sca `p_hi' = `p1'[`anchor'+5, 1]
if "`fromto'"=="fromto" {
mat `dchange'[`i', 7] = `p_lo'
mat `dchange'[`i', 8] = `p_hi'
}
mat `dchange'[`i', 3*`dchcol'] = `p_hi' - `p_lo'
sca `p_lo' = `p1'[`anchor'+6, 1]
sca `p_hi' = `p1'[`anchor'+7, 1]
if "`fromto'"=="fromto" {
mat `dchange'[`i', 10] = `p_lo'
mat `dchange'[`i', 11] = `p_hi'
}
mat `dchange'[`i', 4*`dchcol'] = `p_hi' - `p_lo'
local i = `i' + 1
} /* while `i' <= `i_to' */
mat rownames `dchange' = `varlist'
*added to make matrix headings stata7 compatible
mat _PEtemp = `dchange''
_peabbv _PEtemp
mat `dchange' = _PEtemp'
*column names for centered change
if "`uncentered'"=="" {
if `delt' == 1 {
mat colnames `dchange' = min->max 0->1 -+1/2 -+sd/2
if "`fromto'"=="fromto" {
mat colnames `dchange' = x=min x=max min->max /*
*/ x=0 x=1 0->1 x-1/2 x+1/2 -+1/2 x-1/2sd x+1/2sd -+sd/2
}
}
else {
mat colnames `dchange' = min->max 0->1 -+d/2 -+sd/2
if "`fromto'"=="fromto" {
mat colnames `dchange' = x=min x=max min->max /*
*/ x=0 x=1 0->1 x-d/2 x+d/2 -+d/2 x-1/2sd x+1/2sd -+sd/2
}
}
}
*column names for uncentered change
else {
if `delt' == 1 {
mat colnames `dchange' = min->max 0->1 +1 +sd
if "`fromto'"=="fromto" {
mat colnames `dchange' = x=min x=max min->max /*
*/ x=0 x=1 0->1 x x+1 +1 x x+sd +sd
}
}
else {
mat colnames `dchange' = min->max 0->1 +delta +sd
if "`fromto'"=="fromto" {
mat colnames `dchange' = x=min x=max min->max /*
*/ x=0 x=1 0->1 x x+delta +delta x-sd x+sd +sd
}
}
}
if "`fromto'"=="fromto" {
mat coleq `dchange' = from to dif from to dif /*
*/ from to dif from to dif
}
* add marginals to output if available
if "`hasmarg'"=="yes" {
mat rownames `margout' = MargEfct
mat roweq `margout' = _
mat `margout' = `margout''
mat `dchange' = `dchange', `margout'
}
* output list discrete change matrix
mat list `dchange', noheader f(%8.4f)
mat `change' = `dchange'' // 2006-02-18 for estout
* list probabilities at tobase if desired
mat temp = r(p0)
mat temp2 = r(p1)
mat `basepr' = temp[1,1] , temp2[1,1]
mat rownames `basepr' = "Pr(y|x)"
if "`label'"=="nolabel" { mat colnames `basepr' = `catvals' }
else { mat colnames `basepr' = `catnms8' }
if "`brief'"=="" { mat list `basepr', noheader f(%8.4f) }
mat `predis' = `basepr' // 2006-02-18 for estout
} /* if "`output'"=="binary" */
*=> COUNT MODELS, but not zt
if "`output'"=="count" & `iszt'==0 {
if "`outcome'"=="" { mat `tmp' = r(mu) }
else { mat `tmp' = r(p`outcome') }
local i = 1
local i_to : word count `varlist'
mat `dchange' = J(`i_to', 4, 0)
local dchcol 1
if "`fromto'"=="fromto" {
mat `dchange' = J(`i_to', 12, 0)
local dchcol 3
}
* cycle through all variables specified in varlist
while `i' <= `i_to' {
* calculate discrete change and put in dchange matrix
local anchor = (`i' * 8) - 6
sca `tmp_lo' = `tmp'[`anchor', 1]
sca `tmp_hi' = `tmp'[`anchor'+1, 1]
if "`fromto'"=="fromto" {
mat `dchange'[`i', 1] = `tmp_lo'
mat `dchange'[`i', 2] = `tmp_hi'
}
mat `dchange'[`i', `dchcol'*1] = `tmp_hi' - `tmp_lo'
sca `tmp_lo' = `tmp'[`anchor'+2, 1]
sca `tmp_hi' = `tmp'[`anchor'+3, 1]
if "`fromto'"=="fromto" {
mat `dchange'[`i', 4] = `tmp_lo'
mat `dchange'[`i', 5] = `tmp_hi'
}
mat `dchange'[`i', `dchcol'*2] = `tmp_hi' - `tmp_lo'
sca `tmp_lo' = `tmp'[`anchor'+4, 1]
sca `tmp_hi' = `tmp'[`anchor'+5, 1]
if "`fromto'"=="fromto" {
mat `dchange'[`i', 7] = `tmp_lo'
mat `dchange'[`i', 8] = `tmp_hi'
}
mat `dchange'[`i', `dchcol'*3] = `tmp_hi' - `tmp_lo'
sca `tmp_lo' = `tmp'[`anchor'+6, 1]
sca `tmp_hi' = `tmp'[`anchor'+7, 1]
if "`fromto'"=="fromto" {
mat `dchange'[`i', 10] = `tmp_lo'
mat `dchange'[`i', 11] = `tmp_hi'
}
mat `dchange'[`i', `dchcol'*4] = `tmp_hi' - `tmp_lo'
local i = `i' + 1
}
mat rownames `dchange' = `varlist'
*added to make matrix headings stata7 compatible
mat _PEtemp = `dchange''
_peabbv _PEtemp
mat `dchange' = _PEtemp'
*column names for centered change
if "`uncentered'" == "" {
*unit change
if `delt' == 1 {
mat colnames `dchange' = min->max 0->1 -+1/2 -+sd/2
if "`fromto'"=="fromto" {
mat colnames `dchange' = x=min x=max min->max /*
*/ x=0 x=1 0->1 x-1/2 x+1/2 -+1/2 x-1/2sd x+1/2sd -+sd/2
}
}
*change specified by delta()
else {
mat colnames `dchange' = min->max 0->1 -+d/2 -+sd/2
if "`fromto'"=="fromto" {
mat colnames `dchange' = x=min x=max min->max /*
*/ x=0 x=1 0->1 x-d/2 x+d/2 -+d/2 x-1/2sd x+1/2sd -+sd/2
}
}
}
*column names for uncentered change
else {
*unit change
if `delt' == 1 {
mat colnames `dchange' = min->max 0->1 +1 +sd
if "`fromto'"=="fromto" {
mat colnames `dchange' = x=min x=max min->max /*
*/ x=0 x=1 0->1 x x+1 -+1 x x+sd +sd
}
}
*change specified by delta
else {
mat colnames `dchange' = min->max 0->1 +delta +sd
if "`fromto'"=="fromto" {
mat colnames `dchange' = x=min x=max min->max /*
*/ x=0 x=1 0->1 x x+delta +delta x x+sd +sd
}
}
}
if "`fromto'"=="fromto" {
mat coleq `dchange' = from to dif from to dif from /*
*/ to dif from to dif
}
if "`hasmarg'"=="yes" & "`outcome'"=="" {
mat rownames `margout' = MargEfct
mat roweq `margout' = _
mat `margout' = `margout''
mat `dchange' = `dchange', `margout'
}
mat list `dchange', noheader f(%8.4f)
if "`outcome'"=="" {
local i = 0
mat `temp' = r(mu)
sca `mu' = `temp'[1,1]
mat `predis' = `mu' // 2006-02-18 for estout
mat rownames `predis' = exp(xb) // 2006-02-18 for estout
if "`brief'"=="" { di _n in g "exp(xb): " in y %8.4f `mu' }
}
else {
local i = 0
while `i' <= `max_i' {
mat `temp' = r(p`i')
mat `basepr' = nullmat(`basepr') , `temp'[1, 1]
local cntvals "`cntvals'`i' "
local i = `i' + 1
}
mat rownames `basepr' = "Pr(y|x)"
mat colnames `basepr' = `cntvals'
if "`brief'"=="" { mat list `basepr', noheader f(%8.4f) }
mat `predis' = `basepr' // 2006-02-18 for estout
mat rownames `predis' = "Pr(y|x)" // 2006-02-18 for estout
}
mat `change' = `dchange'' // 2006-02-18 for estout
}
*=> ZT COUNT MODELS 19Feb2005
if `iszt'==1 {
if "`conditional'"=="" {
local type ""
}
else {
local type "C"
}
* grab conditional or not based on type
if "`outcome'"=="" { mat `tmp' = r(`type'mu) }
else { mat `tmp' = r(`type'p`outcome') }
local i = 1
local i_to : word count `varlist'
mat `dchange' = J(`i_to', 4, 0)
local dchcol 1
if "`fromto'"=="fromto" {
mat `dchange' = J(`i_to', 12, 0)
local dchcol 3
}
* cycle through all variables specified in varlist
while `i' <= `i_to' {
* calculate discrete change and put in dchange matrix
local anchor = (`i' * 8) - 6
sca `tmp_lo' = `tmp'[`anchor', 1]
sca `tmp_hi' = `tmp'[`anchor'+1, 1]
if "`fromto'"=="fromto" {
mat `dchange'[`i', 1] = `tmp_lo'
mat `dchange'[`i', 2] = `tmp_hi'
}
mat `dchange'[`i', `dchcol'*1] = `tmp_hi' - `tmp_lo'
sca `tmp_lo' = `tmp'[`anchor'+2, 1]
sca `tmp_hi' = `tmp'[`anchor'+3, 1]
if "`fromto'"=="fromto" {
mat `dchange'[`i', 4] = `tmp_lo'
mat `dchange'[`i', 5] = `tmp_hi'
}
mat `dchange'[`i', `dchcol'*2] = `tmp_hi' - `tmp_lo'
sca `tmp_lo' = `tmp'[`anchor'+4, 1]
sca `tmp_hi' = `tmp'[`anchor'+5, 1]
if "`fromto'"=="fromto" {
mat `dchange'[`i', 7] = `tmp_lo'
mat `dchange'[`i', 8] = `tmp_hi'
}
mat `dchange'[`i', `dchcol'*3] = `tmp_hi' - `tmp_lo'
sca `tmp_lo' = `tmp'[`anchor'+6, 1]
sca `tmp_hi' = `tmp'[`anchor'+7, 1]
if "`fromto'"=="fromto" {
mat `dchange'[`i', 10] = `tmp_lo'
mat `dchange'[`i', 11] = `tmp_hi'
}
mat `dchange'[`i', `dchcol'*4] = `tmp_hi' - `tmp_lo'
local i = `i' + 1
}
mat rownames `dchange' = `varlist'
*added to make matrix headings stata7 compatible
mat _PEtemp = `dchange''
_peabbv _PEtemp
mat `dchange' = _PEtemp'
*column names for centered change
if "`uncentered'" == "" {
*unit change
if `delt' == 1 {
mat colnames `dchange' = min->max 0->1 -+1/2 -+sd/2
if "`fromto'"=="fromto" {
mat colnames `dchange' = x=min x=max min->max /*
*/ x=0 x=1 0->1 x-1/2 x+1/2 -+1/2 x-1/2sd x+1/2sd -+sd/2
}
}
*change specified by delta()
else {
mat colnames `dchange' = min->max 0->1 -+d/2 -+sd/2
if "`fromto'"=="fromto" {
mat colnames `dchange' = x=min x=max min->max /*
*/ x=0 x=1 0->1 x-d/2 x+d/2 -+d/2 x-1/2sd x+1/2sd -+sd/2
}
}
}
*column names for uncentered change
else {
*unit change
if `delt' == 1 {
mat colnames `dchange' = min->max 0->1 +1 +sd
if "`fromto'"=="fromto" {
mat colnames `dchange' = x=min x=max min->max /*
*/ x=0 x=1 0->1 x x+1 -+1 x x+sd +sd
}
}
*change specified by delta
else {
mat colnames `dchange' = min->max 0->1 +delta +sd
if "`fromto'"=="fromto" {
mat colnames `dchange' = x=min x=max min->max /*
*/ x=0 x=1 0->1 x x+delta +delta x x+sd +sd
}
}
}
if "`fromto'"=="fromto" {
mat coleq `dchange' = from to dif from to dif from /*
*/ to dif from to dif
}
if "`hasmarg'"=="yes" & "`outcome'"=="" {
mat rownames `margout' = MargEfct
mat roweq `margout' = _
mat `margout' = `margout''
mat `dchange' = `dchange', `margout'
}
mat list `dchange', noheader f(%8.4f)
mat `change' = `dchange'' // 2006-02-18 for estout
if "`outcome'"=="" {
local i = 0
mat `temp' = r(mu)
sca `mu' = `temp'[1,1]
mat `predis' = `mu' // 2006-02-18 for estout
mat rownames `predis' = exp(xb) // 2006-02-18 for estout
if "`brief'"=="" { di _n in g "exp(xb): " in y %8.4f `mu' }
}
else {
local i = 0
while `i' <= `max_i' {
mat `temp' = r(p`i')
mat `basepr' = nullmat(`basepr') , `temp'[1, 1]
local cntvals "`cntvals'`i' "
local i = `i' + 1
}
mat rownames `basepr' = "Pr(y|x)"
mat colnames `basepr' = `cntvals'
if "`brief'"=="" { mat list `basepr', noheader f(%8.4f) }
mat `predis' = `basepr' // 2006-02-18 for estout
mat rownames `predis' = "Pr(y|x)" // 2006-02-18 for estout
}
}
*=> NOMINAL and ORDINAL
* jsl 10/23/00 - add average absolute discrete change
if "`output'"=="nomord" {
local dchcol 1
if "`fromto'"=="fromto" { local dchcol 3 }
local i = 1
local i_to : word count `varlist'
* loop over variables
tempname a01 a1 asd arange amarg // changed 23oct2007 bj
mat `amarg' = J(1,`i_to',0) // added 23oct2007 bj
while `i' <= `i_to' {
scalar `a01' = 0
scalar `a1' = 0
scalar `asd' = 0
scalar `arange' = 0
local ncats1 = `ncats' + 1
mat `vchange' = J(4, `ncats1', 0)
if "`fromto'"=="fromto" { mat `vchange' = J(12, `ncats1', 0) }
local anchor = (`i' * 8) - 6
local i2 = 2
local i2_to = `ncats1'
* loop over categories
while `i2' <= `i2_to' {
local tmp = `i2' - 1
mat `temp' = r(p`tmp')
sca `p_lo' = `temp'[`anchor', 1]
sca `p_hi' = `temp'[`anchor'+1, 1]
if "`fromto'"=="fromto" {
mat `vchange'[1, `i2'] = `p_lo'
mat `vchange'[2, `i2'] = `p_hi'
}
* range
mat `vchange'[`dchcol'*1, `i2'] = `p_hi' - `p_lo'
scalar `arange' = `arange' + abs(`p_hi' - `p_lo')/`ncats'
mat `vchange'[`dchcol'*1, 1] = `arange'
sca `p_lo' = `temp'[`anchor'+2, 1]
sca `p_hi' = `temp'[`anchor'+3, 1]
if "`fromto'"=="fromto" {
mat `vchange'[4, `i2'] = `p_lo'
mat `vchange'[5, `i2'] = `p_hi'
}
* 0->1
mat `vchange'[`dchcol'*2, `i2'] = `p_hi' - `p_lo'
scalar `a01' = `a01' + abs(`p_hi' - `p_lo')/`ncats'
mat `vchange'[`dchcol'*2, 1] = `a01'
* -+1
sca `p_lo' = `temp'[`anchor'+4, 1]
sca `p_hi' = `temp'[`anchor'+5, 1]
if "`fromto'"=="fromto" {
mat `vchange'[7, `i2'] = `p_lo'
mat `vchange'[8, `i2'] = `p_hi'
}
mat `vchange'[`dchcol'*3, `i2'] = `p_hi' - `p_lo'
scalar `a1' = `a1' + abs(`p_hi' - `p_lo')/`ncats'
mat `vchange'[`dchcol'*3, 1] = `a1'
* -+sd
sca `p_lo' = `temp'[`anchor'+6, 1]
sca `p_hi' = `temp'[`anchor'+7, 1]
if "`fromto'"=="fromto" {
mat `vchange'[10, `i2'] = `p_lo'
mat `vchange'[11, `i2'] = `p_hi'
}
mat `vchange'[`dchcol'*4, `i2'] = `p_hi' - `p_lo'
scalar `asd' = `asd' + abs(`p_hi' - `p_lo')/`ncats'
mat `vchange'[`dchcol'*4, 1] = `asd'
local i2 = `i2' + 1
} /* loop over categories */
local var : word `i' of `varlist'
* column names for centered change
if "`uncentered'"=="" {
if `delt'==1 {
mat rownames `vchange' = "Min->Max" " 0->1" " -+1/2" /*
*/ " -+sd/2"
if "`fromto'"=="fromto" {
mat rownames `vchange' = " x=min" " x=max" "min->max" /*
*/ " x=0" " x=1" " 0->1" " x-1/2" " x+1/2" /*
*/ " -+1/2" " x-1/2sd" " x+1/2sd" " -+sd/2"
}
}
else {
mat rownames `vchange' = "Min->Max" " 0->1" " -+d/2" /*
*/ " -+sd/2"
if "`fromto'"=="fromto" {
mat rownames `vchange' = " x=min" " x=max" "min->max" /*
*/ " x=0" " x=1" " 0->1" " x-d/2" " x+d/2" /*
*/ " -+d/2" " x-1/2sd" " x+1/2sd" " -+sd/2"
}
}
}
* uncentered change
else {
if `delt'==1 {
mat rownames `vchange' = "Min->Max" " 0->1" " +1" /*
*/ " +sd"
if "`fromto'"=="fromto" {
mat rownames `vchange' = " x=min" " x=max" "min->max" /*
*/ " x=0" " x=1" " 0->1" " x" " x+1" /*
*/ " +1" " x" " x+sd" " +sd"
}
}
else {
mat rownames `vchange' = "Min->Max" " 0->1" " +delta" /*
*/ " +sd"
if "`fromto'"=="fromto" {
mat rownames `vchange' = " x=min" " x=max" "min->max" /*
*/ " x=0" " x=1" " 0->1" " x" " x+delta" /*
*/ " +delta" " x" " x+sd" " +sd"
}
}
}
if "`fromto'"=="fromto" {
mat roweq `vchange' = from to dif from to dif from /*
*/ to dif from to dif
}
*=> save PE_dc with discrete change values; used by mlogplot and mlogview
tempname zeros tempmat
* 1 row x ncats with 0's
mat `zeros' = J(1, `ncats', 0)
mat rownames `zeros' = " void"
* is it binary?
capture assert `var' == 0 | `var' == 1 | `var' == . `if' `in'
* if binary, only 0/1 in 2nd row
if _rc == 0 {
* DROP 16Nov2005 1.6.9
* mat `tempmat' = `zeros' \ `vchange'[1,2...] \ `zeros' \ `zeros' \ `zeros'
* 16Nov2005 1.6.9
mat `tempmat' = `vchange'[2,2...] \ `vchange'[1,2...] \ `zeros' /*
*/ \ `zeros' \ `zeros'
} /* else, 1: min/max 2:null 3:1 4:sd */
else {
/* DROP 16Nov2005 1.6.9
* contains 0->1, zeros, -+1, -+sd
mat `tempmat' = `vchange'[2,2...] \ /*
*/ `zeros' \ `vchange'[3..4,2...] \ `zeros'
*/
* 16Nov2005 1.6.9
* contains 0->1, min->max, -+1, -+sd
mat `tempmat' = `vchange'[2,2...] \ /*
*/ `vchange'[1,2...] \ `vchange'[3..4,2...] \ `zeros'
}
mat roweq `tempmat' = `var'
if "`i'"=="1" {
mat PE_dc = `tempmat'
if "`label'"=="nolabel" { mat colnames PE_dc = `catvals' }
else { mat colnames PE_dc = `catnms8' }
}
if "`i'"!="1" {
mat PE_dc = PE_dc \ `tempmat'
}
* grab all info on change
mat `nomtemp' = nullmat(`nomtemp') \ `vchange' // 2006-02-18 for estout
*=> set up matrices for output
if "`label'"=="nolabel" {
mat colnames `vchange' = "Avg|Chg|" `catvals'
}
else {
mat colnames `vchange' = "Avg|Chg|" `catnms8'
}
if "`outcome'"=="" {
* is 0/1 variable
capture assert `var' == 0 | `var' == 1 | `var' == . `if' `in'
if "`fromto'"=="fromto" {
if _rc == 0 { mat `vchange' = `vchange'[4..6, 1...] }
else {
tempname vchang1 vchang2
mat `vchang1' = `vchange'[1..3, 1...]
mat `vchang2' = `vchange'[7..., 1...]
mat `vchange' = `vchang1' \ `vchang2'
}
}
else {
if _rc == 0 { mat `vchange' = `vchange'[2, 1...] }
else {
tempname vchang1 vchang2
mat `vchang1' = `vchange'[1, 1...]
mat `vchang2' = `vchange'[3..., 1...]
mat `vchange' = `vchang1' \ `vchang2'
}
}
if "`hasmarg'"=="yes" {
capture assert `var' == 0 | `var' == 1 /*
*/ | `var' == . `if' `in'
if _rc != 0 {
mat `vmarg' = `margout'[`i', 1...]
* compute avg abs discrete change
local k = 1
* amarg changes made in 1.8.0 for estout returns
*tempname amarg // removed 23oct2007 bj
*scalar `amarg' = 0 // removed 23oct2007 bj
while `k' <= `ncats' {
mat `amarg'[1,`i'] = `amarg'[1,`i'] + abs(`vmarg'[1,`k']) // changed 23oct2007 bj
local k = `k' + 1
}
* jf 5/20/03
mat `amarg'[1,`i'] = `amarg'[1,`i'] / `ncats' // changed 23oct2007 bj
mat `vmarg' = (`amarg'[1,`i'],`vmarg') // changed 23oct2007 bj
mat rownames `vmarg' = MargEfct
mat roweq `vmarg' = _
mat `vchange' = `vchange' \ `vmarg'
}
}
di _n in y "`var'" _c
mat list `vchange', noheader
mat roweq `vchange' = `var'
mat `dchange' = nullmat(`dchange') \ `vchange'
} /* "`outcome'"=="" */
else {
* mat `vchange' = `vchange'[1..., `outcome']
* 1.7.1 06Jan2007
* +1 since average in in first column
mat `vchange' = `vchange'[1..., `outcome'+1]
mat `vchange' = `vchange''
mat rownames `vchange' = `var'
mat `dchange' = nullmat(`dchange') \ `vchange'
}
local i = `i' + 1
} /* while `i' <= `i_to' */
if "`outcome'"!="" {
if "`hasmarg'"=="yes" {
mat `margout' = `margout'[1..., `outcome']
mat colnames `margout' = MargEfct
mat coleq `margout' = _
mat `dchange' = `dchange' , `margout'
}
*added to make matrix headings stata7 compatible
mat _PEtemp = `dchange''
* 2.5.2
local outcmvnm "`outcmv'"
return mat change`outcmvnm' = _PEtemp, copy
* return mat change`outcmv' = _PEtemp, copy // added 23oct2007 bj
_peabbv _PEtemp
mat `dchange' = _PEtemp'
mat list `dchange', noheader
mat `dchange' = `dchange''
}
local i = 1
while `i' <= `ncats' {
mat temp = r(p`i')
mat `basepr' = nullmat(`basepr') , temp[1, 1]
local i = `i' + 1
}
mat rownames `basepr' = "Pr(y|x)"
if "`label'"=="nolabel" { mat colnames `basepr' = `catvals' }
else { mat colnames `basepr' = `catnms8' }
if "`brief'"=="" { mat list `basepr', noheader }
// rearrange info to be returned 2006-02-18 for estout
if "`outcome'"=="" { // if-condition added 23oct2007 bj
tempname tempmat mtemp // changed 24oct2007 bj
local i = 1
while `i' <= (`ncats'+1) {
* move col i into one column for each variable
local v = 1
while `v' <= `i_to' {
local nrowper = 4 + 8*("`fromto'"=="fromto") // rows of info per variable - changed 07nov2007 bj
local rst = 1+ ((`v'-1)*`nrowper')
local ren = `rst' + `nrowper' - 1
mat `tempmat' = nullmat(`tempmat') , `nomtemp'[`rst'..`ren'', `i']
local ++v
}
mat colnames `tempmat' = `varlist'
if `i'==1 {
if "`hasmarg'"=="yes" { // block added 23oct2007 bj
mat rowname `amarg' = MargEfct
mat `tempmat' = `tempmat' \ `amarg'
}
return mat changemn = `tempmat'
}
else {
local c = `i' - 1
local catnum : word `c' of `catvals'
* 2.5.1 if negative, replace - with _ 2009-12-10
if `catnum'<0 {
local catnum = abs(`catnum')
local catnum "_`catnum'"
}
tempname change`catnum'
* 1.7.1 add marg to return matrix
if "`hasmarg'"=="yes" { // if-condition added 23oct2007 bj
mat `mtemp' = `margout'[1...,`c']' // changed 23oct2007 bj
mat rowname `mtemp' = MargEfct
*mat def mtemp = `mtemp' // removed 23oct2007 bj
*mat def tempmat = `tempmat' // removed 23oct2007 bj
mat `tempmat' = `tempmat' \ `mtemp'
}
return mat change`catnum' = `tempmat'
}
local ++i
}
} /* if "`outcome'"=="" */
mat `predis' = `basepr'
} /* if "`output'"=="nomord" */
*=> print base values
if "`brief'"=="" & "`base'"!="nobase" {
if "`input'"=="twoeq" {
di _n in g "base x values for count equation: "
}
mat `tobase' = `tobase' \ `sd'
* 2009-07-10 1.8.1 for Stata 11
mat rownames `tobase' = "x=" "sd_x="
mat _PEtemp = `tobase'
_peabbv _PEtemp
mat list _PEtemp, noheader f(%8.0g)
if "`input'"=="twoeq" {
di _n in g "base x values for binary equation: "
mat `tobase2' = `tobase2' \ `sd2'
* 2009-07-10 1.8.1 for Stata 11
mat rownames `tobase2' = "x=" "sd_x="
mat _PEtemp = `tobase2'
_peabbv _PEtemp
mat list _PEtemp, noheader f(%8.0g)
}
}
*=> Help option
if "`help'"=="help" {
di
di in g " Pr(y|x): probability of observing each y for "/*
*/ "specified x values"
di in g "Avg|Chg|: average of absolute value of the change"/*
*/ " across categories"
di in g "Min->Max: change in predicted probability as x"/*
*/ " changes from its minimum to"
di in g " its maximum"
di in g " 0->1: change in predicted probability as x"/*
*/ " changes from 0 to 1"
if "`uncentered'"=="" {
if `delt'==1 {
di in g " -+1/2: change in predicted probability as x"/*
*/ " changes from 1/2 unit below"
di in g " base value to 1/2 unit above"
}
else {
di in g " -+d/2: change in predicted probability as x"/*
*/ " changes from " `delthlf' " units"
di in g " below base value to "`delthlf' " units"/*
*/ " above"
}
}
else {
if `delt'==1 {
di in g " +1: change in predicted probability as x"/*
*/ " increases by 1 unit"
}
else {
di in g " +delta: change in predicted probability as x"/*
*/ " increases by " `delt' " units"
}
}
if "`uncentered'"=="" {
di in g " -+sd/2: change in predicted probability as x"/*
*/ " changes from 1/2 standard"
di in g " dev below base to 1/2 standard"/*
*/ " dev above"
}
else {
di in g " +sd: change in predicted probability as x"/*
*/ " increases by a standard dev"
}
di in g "MargEfct: the partial derivative of the predicted"/*
*/ " probability/rate with"
di in g " respect to a given independent variable"
}
// 2006-02-18 returns for estout
mat rown `tobase' = X // 23oct2007 bj
mat `baseval' = `tobase'[1,1...] \ `baseval'[2...,1...] // 23oct2007 bj
* combine base values and name equations if zip or zinb
if "`input'"=="twoeq" {
mat rown `tobase2' = X // added 23oct2007 bj
mat `basezi' = `tobase2'[1,1...] \ `basezi'[2...,1...] // added 23oct2007 bj
matrix colnames `basezi' = inflate:
local eqnm "`e(depvar)':"
matrix colnames `baseval' = `eqnm'
matrix `baseval' = `baseval' , `basezi'
}
return matrix baseval = `baseval'
if "`output'"!="nomord" { return matrix change = `change' } // changed 23oct2007 bj
return matrix predval = `predis'
return scalar delta = `delt' // 05nov2007 bj
return scalar centered = ("`uncentered'"=="") // 05nov2007 bj
if "`outcome'"!="" { // 23oct2007 bj
return scalar outcome = `outcmv'
}
return local modeltype `"`io'"' // 23oct2007 bj
* return names and values of outcome categories
tempname catn
if "`catvals'"!="" {
local i = 1
while `i' <= `ncats' {
local valchk : word `i' of `catvals'
local nmchk : word `i' of `catnms'
mat `catn' = nullmat(`catn') \ `valchk'
local ++i
}
}
else {
matrix `catn' = J(1,1,.)
local catnms = ""
}
matrix `catn' = `catn''
matrix colnames `catn' = `catnms'
matrix rownames `catn' = "`e(depvar)'"
return matrix catval = `catn'
end
exit
* version 1.6.8 13Apr2005
* version 1.6.7c 27Mar2005 slogit
* version 1.6.7b 19Feb2005 zt
* version 1.6.6 20May2003
* version 1.6.9 - 19May2006
* - Add min->max change to PE_dc for mlogplot
* - required for mlogplot v1.6.8 to plot changes over range
* version 1.7.1 jsl 06Jan2007 for estout
* - outcome() fixed for ord and nom
* version 1.7.2 - 07nov2007 Ben Jann changes for estout
* - -fromto- results were not returned correctly with nomord models - this is fixed
* - brief option caused error - this is fixed
* - returns r(outcome) if -outcome()- specified
* - returns type of model in r(modeltype)
* - returns marginal effects now also in r(changemn)
* - no longer crashes on nomorg models without marginals (i.e. -slogit-)
* - returns correct basevals now if x() is specified
* - returns results now only for the specified outcome if -outcome()- is specified
* - no longer returns r(change) for nomord models
* version 1.8.0 2008-02-16 sl
* - revised to work with estout
* - added mprobit
* version 1.8.1 2009-07-10
* - sd(x) fix for Stata 11
* version 1.9.0 jsl 2009-09-19
* - fix mlogit for e(b) in stata 11
* version 2.5.0 2009-10-28 jsl
* - stata 11 update for returns from -mlogit-