📄 mfx.ado
字号:
local total = `eqnum'[1,`ncol'] /* how many equations */
mat `dfdxb' = J(1, `total', 0)
local i = 1
while `i' <= `total' {
if (`trace'>=2) {
di as text _n "equation i= " as result `i' " " _c
}
tempname b dfdx
mat `b' = `B'
local j=0
local k=1
while `k'<=`ncol' & `j'==0 {
if `eqnum'[1,`k'] == `i' & `b'[1,`k']!=0 {
local j = `k'
}
local k=`k'+1
}
if `j'==0{
di as error _n "equation with all zero coefficients "/*
*/"found in linear method; try " in smcl /*
*/"{help j_mfxnonlinear##|_new:nonlinear}"/*
*/ as error " option"
exit 430
}
local name : word `j' of `cname'
cap confirm var `name'
if _rc { /* constant only */
L_dfdb `X' `j' "`predopt'" `lny'
mat `dfdxb'[1,`i'] = r(dfdb)
}
else {
dfdx_cts `X' `j' "`predopt'" `lny' `trace'
scalar `dfdx' = r(dfdx)
mat `dfdxb'[1,`i'] = `dfdx'/`b'[1,`j']
}
if (`trace'>=2) {
di as text ": df/d(xb) = " as result `dfdxb'[1,`i']
}
local i = `i' + 1
}
return matrix dfdxb `dfdxb'
end
*----------------------------------------------------------
program define L_dmdb, rclass
args X predopt lny trace
tempname B eqnum dmdxb dmdij
mat `B' = e(b)
local ncol = colsof(`B')
mat `eqnum' = J(1, `ncol', 1)
local ename : coleq `B'
local cname : colname `B'
if "`ename'" != "" {
tokenize `ename'
local j = 1
local i = 1
while "`1'" != "" {
mat `eqnum'[1,`i'] = `j'
if "`2'" != "`1'" {
local j = `j' + 1
}
mac shift
local i = `i' + 1
}
}
local total = `eqnum'[1,`ncol'] /* how many equations */
mat `dmdxb' = J(`total', `total', 0)
local i = 1
while `i' <= `total' {
if (`trace'>=2) {
di as text _n "equation k = " as result `i' ": "
}
local k = 1
while (`eqnum'[1,`k'] != `i' | `B'[1,`k'] ==0) & `k'<`ncol' {
local k = `k' + 1
}
local j = 1
while `j' <= `i' {
local l = 1
while (`eqnum'[1, `l'] != `j' | `B'[1,`l'] ==0) & `l'<`ncol'{
local l = `l' + 1
}
local name : word `l' of `cname'
cap confirm var `name'
if _rc {
local namek : word `k' of `cname'
cap confirm var `namek'
if `i' == `j' | _rc {
scalar `dmdij' = 0
}
else {
L2_Dxbxb `dmdij' `X' `l' `k' /*
*/ "`predopt'" `lny' `trace'
scalar `dmdij' = `dmdij'/`B'[1,`k']
}
}
else {
L2_Dxbxb `dmdij' `X' `k' `l' "`predopt'" /*
*/ `lny' `trace'
scalar `dmdij' = `dmdij'/`B'[1,`l']
}
mat `dmdxb'[`i', `j'] = `dmdij'
mat `dmdxb'[`j', `i'] = `dmdij'
if (`trace'>=2) {
di as text "k= " as result `i' /*
*/ as text ", l= " as result `j' _c
di as text ": d^2f/d(xb_k)d(xb_l) = "/*
*/ as result `dmdij'
}
local j = `j' + 1
}
local i = `i' + 1
}
return mat dmdxb `dmdxb'
return mat eqnum `eqnum'
end
program define L2_Dxbxb
args dmdij X k l predopt lny trace
tempname h
local epsf 1e-3
scalar `h' = (abs(`X'[1,`l']) + `epsf')*`epsf'
preserve
AddX `X'
L2_GetH `h' `X' `k' `l' "`predopt'" `lny' `trace'
if `h' == 0 {
scalar `dmdij' = 0
}
else {
tempname X1 f1 f2
mat `X1' = `X'
mat `X1'[1,`l'] = `X'[1,`l'] + `h'/2
L2_GetF `f1' `X1' `k' "`predopt'" `lny' `trace'
mat `X1'[1,`l'] = `X'[1,`l'] - `h'/2
L2_GetF `f2' `X1' `k' "`predopt'" `lny' `trace'
scalar `dmdij' = (`f1'-`f2')/`h'
}
restore
end
program define L2_GetH
args h X k l predopt lny trace
tempname f0 f1 goal0 goal1 diff lh uh X1
L2_GetF `f0' `X' `k' "`predopt'" `lny' `trace'
mat `X1' = `X'
mat `X1'[1,`l'] = `X1'[1,`l'] + `h'
L2_GetF `f1' `X1' `k' "`predopt'" `lny' `trace'
scalar `diff' = abs(`f0' - `f1')
if `diff' < abs(`f0' + 1e-7)*1e-7 {
scalar `h' = 0
}
else {
local ep0 1e-5
local ep1 1e-3
scalar `goal0' = abs(`f0'+`ep0')*`ep0'
scalar `goal1' = abs(`f0'+`ep1')*`ep1'
local flag1 1
local flag2 1
local loop 0
while (`diff' < `goal0' | `diff' > `goal1' ) {
if (`trace'>=3 & `loop'==0) {
di as text _n "-----Iteration (dx) for "/*
*/" d^2f/d(xb_k)d(xb_l)-----"
}
if `diff' < `goal0' {
scalar `lh' = `h'
local flag1 0
if `flag2' {
scalar `uh' = 2*`h'
}
}
else {
scalar `uh' = `h'
local flag2 0
if `flag1' {
scalar `lh' = 0.5*`h'
}
}
local loop=`loop'+1
if (`trace'>=3 ) {
di as text "`loop' " _c
}
scalar `h' = (`lh'+`uh')/2
if (abs(`uh'-`lh') < 1e-15) {
scalar `h' =.
exit
}
else {
if (abs(`uh'-`lh') > 1e5) {
scalar `h' =0
exit
else {
if `loop'>100 {
di as error _n /*
*/ "cannot find suitable change "/*
*/"in x for linear method; try " /*
*/ in smcl /*
*/"{help j_mfxnonlinear##|_new:nonlinear}"/*
*/ as error " option"
exit 430
}
}
}
mat `X1'[1,`l'] = `X'[1,`l'] + `h'
L2_GetF `f1' `X1' `k' "`predopt'" `lny' `trace'
scalar `diff' = abs(`f0' - `f1')
}
}
end
program define L2_GetF
args f X k predopt lny trace
tempname B
mat `B' = e(b)
local cname : colname `B'
local name : word `k' of `cname'
cap confirm var `name'
if _rc {
L_dfdb `X' `k' "`predopt'" `lny' `trace'
scalar `f' = r(dfdb)
}
else {
dfdx_cts `X' `k' "`predopt'" `lny' `trace'
scalar `f' = r(dfdx)/`B'[1,`k']
}
if `trace'>=4{
di as text " dfdxb = " `f'
}
end
*----------------------------------------------------------
program define L_dfdb, rclass
args X i predopt lny trace
tempname est0 B
est hold `est0', copy
preserve
AddX `X'
mat `B' = e(b)
tempname h dfdb
local epsf 1e-6
scalar `h' = (abs(`B'[1,`i']) + `epsf')*`epsf'
bGetH `h' `X' `B' `i' "`predopt'" `lny'
if `h' == 0 {
scalar `dfdb' = 0
}
else bGetDfdb `dfdb' `h' `B' `i' "`predopt'" `lny'
return scalar dfdb = `dfdb'
return scalar h = `h'
restore
est unhold `est0'
end
program define bGetH
args h X B i predopt lny
tempname f0 f1 B1 goal0 goal1 diff lh uh
bGetF `f0' `B' "`predopt'" `lny'
mat `B1' = `B'
mat `B1'[1,`i'] = `B'[1,`i'] + `h'
bGetF `f1' `B1' "`predopt'" `lny'
scalar `diff' = abs(`f0' - `f1')
if `diff' < abs(`m0' + 1e-8)*1e-8 {
scalar `h' = 0
}
else {
local ep0 1e-7
local ep1 1e-6
scalar `goal0' = abs(`f0'+`ep0')*`ep0'
scalar `goal1' = abs(`f0'+`ep1')*`ep1'
local flag1 1
local flag2 1
local loop 0
while (`diff' < `goal0' | `diff' > `goal1' ) {
if `diff' < `goal0' {
scalar `lh' = `h'
local flag1 0
if `flag2' {
scalar `uh' = 2*`h'
}
}
else {
scalar `uh' = `h'
local flag2 0
if `flag1' {
scalar `lh' = 0.5*`h'
}
}
scalar `h' = (`lh'+`uh')/2
local loop=`loop'+1
if abs(`uh'-`lh') < 1e-15 | abs(`uh'-`lh') > 1e15 /*
*/ | `loop'>100 {
di as error _n "cannot find suitable change "/*
*/"in b for linear method; try "/*
*/"{help j_mfx_nonlinear##|_new:nonlinear} option"
exit 430
}
mat `B1'[1,`i'] = `B'[1,`i'] + `h'
bGetF `f1' `B1' "`predopt'" `lny'
scalar `diff' = abs(`f0' - `f1')
}
}
end
program define bGetF, eclass
args f B predopt lny
tempname y V C
mat `C' = `B'
mat `V' = e(V)
est post `C' `V', noclear
$T_mfver qui predict double `y' , `predopt'
if `lny' {
scalar `f' = ln(`y'[1])
}
else scalar `f' = `y'[1]
end
program define bGetDfdb
args dfdb h B i predopt lny
tempname B1 f1 f2
mat `B1' = `B'
mat `B1'[1,`i'] = `B'[1, `i'] + `h'/2
bGetF `f1' `B1' "`predopt'" `lny'
mat `B1'[1,`i'] = `B'[1, `i'] - `h'/2
bGetF `f2' `B1' "`predopt'" `lny'
scalar `dfdb' = (`f1' - `f2') / `h'
end
*----------------------------------------------------------
program define Replay
syntax , [Level(cilevel)]
local type "`e(Xmfx_type)'"
tempname y X B SE
scalar `y' = e(Xmfx_y)
cap mat `X' = e(Xmfx_X)
if _rc!=0 {
di as error "no mfx results found"
exit 301
}
cap mat list e(Xmfx_se_`type')
if _rc {
local se 0
}
else local se 1
mat `B' = e(Xmfx_`type')
if `se' {
mat `SE' = e(Xmfx_se_`type')
}
local cnum = colsof(`B')
if "`type'" == "dydx" {
local title "dy/dx"
}
if "`type'" == "eyex" {
local title "ey/ex"
}
if "`type'" == "dyex" {
local title "dy/ex"
}
if "`type'" == "eydx" {
local title "ey/dx"
}
if "`e(Xmfx_predict)'" != "" {
local predict ", `e(Xmfx_predict)'"
}
else local predict
if `"`e(prefix)'"' == "" {
if "`e(cmd2)'" != "" {
local cmd "`e(cmd2)'"
}
else{
local cmd "`e(cmd)'"
}
}
else {
local cmd = "`e(prefix)':`e(cmdname)'"
}
di
if "`type'" == "dydx" {
di in gr "Marginal effects after `cmd'"
}
else di in gr "Elasticities after `cmd'"
di in gr _col(7) `"y = `e(Xmfx_label_p)' (predict`predict')"'
di in gr _col(10) "= " in ye %10.0g `y'
if `se' {
di in smcl in gr "{hline 9}{c TT}{hline 68}"
Display `X' `B' `SE' "`level'" "`type'" "`title'" `ism' `isv'
}
else {
di in smcl in gr "{hline 33}{c TT}{hline 45}"
Displaynose `X' `B' "`type'" "`title'" `ism' `isv'
}
end
program define Display
args X dfdx se_dfdx level type title
tempname Z
local dummy "`e(Xmfx_dummy)'"
local vars "`e(Xmfx_variables)'"
local discret "`e(Xmfx_discrete)'"
local c = colsof(`dfdx')
scalar `Z' = invnorm(1-(1-`level'/100)/2)
local 1 "variable"
local cil `=string(`level')'
local cil `=length("`cil'")'
if `cil' == 2 {
local lspaces " "
local rspaces " "
}
else if `cil' == 4 {
local lspaces " "
local rspaces " "
}
else {
local lspaces " "
local rspaces " "
}
di in smcl in gr /*
*/ %8s abbrev(`"`1'"',8) " {c |}" _col(17) `"`title'"' /*
*/ _col(26) /*
*/ `"Std. Err."' _col(40) `"z"' _col(45) `"P>|z|"' /*
*/ _col(52) `"[`lspaces'`=strsubdp("`level'")'% C.I. ]"' /*
*/ _col(75) `"X"' _n /*
*/ "{hline 9}{c +}{hline 68}"
local varlist : colnames(`dfdx')
tokenize `varlist'
local i 1
while `i' <= `c' {
local isvar : word `i' of `vars'
if `isvar' {
local isdum : word `i' of `dummy'
if `isdum' & ("`discret'" == "discrete") {
local star "*"
local anydum "true"
}
else local star " "
local C = `dfdx'[1, `i']
local s = `se_dfdx'[1, `i']
local ll = `C' - `Z'*`s'
local ul = `C' + `Z'*`s'
local z = `C'/`s'
local xnames: colnames(`X')
local vnum=colsof(`dfdx')
local k 1
local tmp: word `k' of `xnames'
while "`tmp'"!="``i''" {
local k=`k'+1
local tmp: word `k' of `xnames'
}
local x = `X'[1, `k']
di in smcl in gr %8s /*
*/ abbrev(`"``i''"',8) `"`star'{c |} "' /*
*/ in ye %9.0g `C' `" "'_c
sigfm 5 9 `s'
if `s(code)' {
dis in ye %9s "`s(output)'" `" "' _c
}
else dis in ye %9.0g `s(output)' `" "' _c
di in ye /*
*/ %7.2f `z' `" "' /*
*/ %6.3f 2*normprob(-abs(`z')) `" "' /*
*/ %8.0g `ll' `" "' /*
*/ %8.0g `ul' `" "' /*
*/ %8.6g `x'
}
local i = `i' + 1
}
foreach x in "" "1" "2" {
if (e(Xmfx_off`x')< . ) {
local offvar="`e(offset`x')'"
di in smcl in gr /*
*/ %8s abbrev(`"`offvar'"',8) `" {c |} "' /*
*/ in gr "(offset`x')" `" "' /*
*/ _col(71) %8.6g in ye e(Xmfx_off`x')
}
}
di in smcl in gr "{hline 9}{c BT}{hline 68}"
if `"`anydum'"'==`"true"' {
di in gr `"(*) `title'"' " is for discrete " /*
*/ "change of dummy variable from 0 to 1"
}
end
program define Displaynose
args X dfdx type title
local c = colsof(`dfdx')
local dummy "`e(Xmfx_dummy)'"
local vars "`e(Xmfx_variables)'"
local discret "`e(Xmfx_discrete)'"
local 1 "variable"
di in smcl in gr /*
*/ %32s abbrev(`"`1'"',32) " {c |}" _col(45) `"`title'"' /*
*/ _col(67) `"X"'
di in smcl in gr "{hline 33}{c +}{hline 45}"
local varlist : colnames(`dfdx')
tokenize `varlist'
local i 1
while `i' <= `c' {
local isvar : word `i' of `vars'
if `isvar'==1 {
local isdum : word `i' of `dummy'
if `isdum' & ("`discret'" == "discrete") {
local star "*"
local anydum "true"
}
else local star " "
local C= `dfdx'[1, `i']
local xnames: colnames(`X')
local vnum=colsof(`dfdx')
local k 1
local tmp: word `k' of `xnames'
while "`tmp'"!="``i''" {
local k=`k'+1
local tmp: word `k' of `xnames'
}
local x = `X'[1, `k']
di in smcl in gr %32s abbrev(`"``i''"',32) `"`star'{c |} "'/*
*/ in ye _col(42) %9.0g `C' `" "' /*
*/ _col(62) %8.6g `x'
}
local i = `i' + 1
}
foreach x in "" "1" "2" {
if ("`e(offset`x')'"!="" ) /*
*/ & index("`e(Xmfx_predict)'", "nooffset")==0 {
local offvar="`e(offset`x')'"
di in smcl in gr /*
*/ %32s abbrev(`"`offvar'"',32) `" {c |} "' /*
*/ _col(42) in gr "(offset`x')" `" "' /*
*/ _col(62) %8.6g in ye e(Xmfx_off`x')
}
}
di in smcl in gr "{hline 33}{c BT}{hline 45}"
if `"`anydum'"'==`"true"' {
di in gr `"(*) `title'"' " is for discrete "/*
*/ "change of dummy variable from 0 to 1"
}
end
program define sigfm, sclass
args digits slength number
sret clear
if "`number'" == "0" | "`number'" =="" {
sreturn local output "`number'"
sreturn local code 0
exit
}
tempname a b output input y
scalar `input' = abs(`number')
scalar `a' = log10(`input')
if ( `a' < 0 ) & ( int(`a') != `a' ) {
scalar `a' = `a' - 1
}
if `a' > `digits ' {
scalar `b' = int(`a') - `digits' + 1
scalar `y' = 10^`b'
local output = round(`input', `y')
if `a' >= `slength' - 2 {
if sign(`number') == -1 {
local output "-`output'"
}
sret clear
sreturn local output "`output'"
sreturn local code 0 /* number */
}
else {
sret clear
sreturn local output "`number'"
sreturn local code 0 /* string */
}
}
else if `a' < -`digits' {
scalar `y' = 10^(-`digits')
local output = round(`input', `y')
if "`output'"== "0" {
local output "."
local i = 1
while `i' < = `digits' {
local output "`output'0"
local i = `i' + 1
}
if sign(`number') == -1 {
local output "-`output'"
}
sret clear
sreturn local output "`output'"
sreturn local code 1 /* string */
}
else {
if sign(`number') == -1 {
local output "-`output'"
}
sret clear
sreturn local output "`output'"
sreturn local code 0 /* number */
}
}
else {
if int(`a') > 0 {
scalar `y' = 10^(-(`digits'-int(`a')-1))
}
else scalar `y' = 10^(-`digits')
local output = round(`input', `y')
if sign(`number') == -1 {
local output "-`output'"
}
sret clear
sreturn local output "`output'"
sreturn local code 0 /* string */
}
end
program Clean, rclass
return clear
end
exit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -