📄 hausman.ado
字号:
*! version 3.0.12 01apr2005
program define hausman, rclass
version 8
// translate old syntax into new syntax
gettoken tok : 0, parse(" ,")
if `"`0'"' == "" | `"`tok'"' == "," {
OldSyntax `0'
local 0 `"`r(newsyntax)'"'
if `"`0'"'=="" {
exit 0
}
}
// process new syntax
// undocumented options: syminv sigmaless reveq
syntax [anything] [, Alleqs Constant SIGmamore SIGMALess FORCE /*
*/ SKipeqs(string) SYMINV EQuations(string) REVEQ /*
*/ TCONsistent(str) TEFFicient(str) /*
*/ df(numlist integer >0 <11000 max=1) ]
/*
BEWARE:
<object>1 refers to the always-consistent estimator
<object>2 refers to the efficient-under-Ho estimator,
*/
if `"`: word count `anything''"' == "1" {
local anything `"`anything' ."'
}
est_expand `"`anything'"', min(1) max(2)
local name1 : word 1 of `r(names)'
local name2 : word 2 of `r(names)'
if "`name1'" == "`name2'" {
di as err "the two models need to be different"
exit 198
}
local tname1 `tconsistent'
if `"`tname1'"' == "" {
local tname1 `name1'
}
local tname2 `tefficient'
if `"`tname2'"' == "" {
local tname2 `name2'
}
if `"`equations'"' != "" {
local alleqs ""
local skipeqs ""
Mlist `"`equations'"'
local est1 `s(opt1)'
local est2 `s(opt2)'
if "`reveq'" != "" {
local est2 `s(opt1)'
local est1 `s(opt2)'
}
}
// extract information about models needed in test
tempname hcurrent b1 V1 b2 V2 V12 s2_1 s2_2 res rank chi2 esample d se
_est hold `hcurrent', nullok restore estsystem
forvalues i = 1/2 {
nobreak {
if "`name`i''" != "." {
est_unhold `name`i'' `esample'
}
else {
_est unhold `hcurrent'
}
capture break noisily {
if "`e(cmd2)'" != "" {
local cmd`i' `e(cmd2)'
}
else {
local cmd`i' `e(cmd)'
}
GetbV `name`i'' `b`i'' `V`i''
scalar `s2_`i'' = e(sigma)
if `s2_`i'' == . {
scalar `s2_`i'' = e(rmse)
}
}
local rc = _rc
if "`name`i''" != "." {
est_hold `name`i'' `esample'
}
else {
_est hold `hcurrent', nullok restore estsystem
}
}
if `rc' {
exit `rc'
}
}
// compute test statistic
Strik0 `b1' `V1'
Strik0 `b2' `V2'
if `"`skipeqs'"' != "" {
SkipEqs row `b1' `"`skipeqs'"'
SkipEqs mat `V1' `"`skipeqs'"'
SkipEqs row `b2' `"`skipeqs'"'
SkipEqs mat `V2' `"`skipeqs'"'
}
else if `"`equations'"' != "" {
Select `b1' `V1' "`est1'"
Select `b2' `V2' "`est2'"
}
else if "`alleqs'" == "" {
Get1steq row `b1'
Get1steq mat `V1'
Get1steq row `b2'
Get1steq mat `V2'
}
if "`constant'" == "" {
Rmcons `b1'
Rmcons `V1'
Rmcons `b2'
Rmcons `V2'
}
if "`sigmamore'" != "" | "`sigmaless'" != "" {
if `s2_1' == .| `s2_2' == . {
di as err "Estimators do not save e(sigma) or e(rmse),"
di as err "sigma option not allowed"
exit 198
}
if "`sigmamore'" != "" {
matrix `V1' = ((`s2_2'/`s2_1')^2) * `V1'
}
else {
matrix `V2' = ((`s2_1'/`s2_2')^2) * `V2'
}
}
capture MatConf `b1' `V1' `b2' `V2'
if _rc {
di as err "no coefficients in common; " ///
"specify equations(matchlist)"
di as err "for problems with different equation names."
exit 498
}
matrix `V2' = `V1' - `V2'
SymPosDef `V2'
local posdef `r(posdef)'
MatGinv `V12' `rank' : `V2' `syminv'
matrix `res' = (`b1'-`b2') * `V12' * (`b1'-`b2')'
scalar `chi2' = `res'[1,1]
// display test
Abbrev tname1ab : `"`tname1'"'
Abbrev tname2ab : `"`tname2'"'
di _n as txt ///
_col(18) "{hline 4} Coefficients {hline 4}" _n ///
_col(14) "{c |}" _col(21) "(b)" _col(34) "(B)" ///
_col(49) "(b-B)" ///
_col(59) "sqrt(diag(V_b-V_B))" _n ///
_col(14) "{c |}" _col(17) %~12s `"`tname1ab'"' ///
_col(30) %~12s `"`tname2ab'"' ///
_col(46) "Difference" _col(66) "S.E." _n ///
"{hline 13}{c +}{hline 64}"
local eqnames : coleq `b1'
local uniqeq : list uniq eqnames
local numeq : word count `uniqeq'
local names : colnames `b1'
tokenize `names'
local omit 0
local i 1
while `i' <= colsof(`b1') {
if `numeq' > 1 {
local eq : word `i' of `eqnames'
if "`eq'" != "`holdeq'" {
if `i' != 1 {
di as txt "{hline 13}{c +}{hline 64}"
}
di as res "`eq'" _col(14) as txt "{c |}"
local holdeq `eq'
}
}
scalar `d' = `b1'[1,`i'] - `b2'[1,`i']
scalar `se' = sqrt(`V2'[`i',`i'])
di as txt %12s abbrev("``i''",12) " {c |} " ///
as res _col(18) %9.0g `b1'[1,`i'] ///
_col(31) %9.0g `b2'[1,`i'] ///
_col(47) %9.0g `d' ///
_col(63) %9.0g `se' _c
if "`syminv'" != "" & `V12'[`i',`i'] == 0 {
di " (omitted)" _c
local ++omit
}
di
local ++i
}
di as txt "{hline 13}{c BT}{hline 64}"
di as txt "{ralign 78:b = consistent under Ho and Ha; obtained from `cmd1'}"
di as txt "{ralign 78:B = inconsistent under Ha, efficient under Ho; obtained from `cmd2'}"
if "`df'" == "" {
local df = `rank'
}
di _n as txt " Test: Ho: difference in coefficients not systematic"
di _n as txt "{ralign 25:chi2({res:`=`df''})}" ///
" = (b-B)'[(V_b-V_B)^(-1)](b-B)"
if `chi2' >= 0 {
di as txt _col(27) "= " as res %10.2f `chi2' _n ///
as txt _col(17) "Prob>chi2 = " ///
as res %10.4f chiprob(`df', `chi2')
if ! `posdef' {
dis as txt _col(17) "(V_b-V_B is not positive definite)"
}
}
else {
di as txt _col(27) "=" as res %9.2f `chi2' as txt ///
_col(41) "chi2<0 ==> model fitted on these" _n ///
_col(41) "data fails to meet the asymptotic" _n ///
_col(41) "assumptions of the Hausman test;" _n ///
_col(41) "see {help suest##|_new:suest} for a generalized test"
}
ret scalar p = chiprob(`df', `chi2')
ret scalar df = `df'
ret scalar chi2 = `chi2'
ret scalar rank = `rank'
end
// ============================================================================
// subroutines
// ============================================================================
program define Get1steq /* row|mat matname */
args type m
local eq : coleq(`m')
local eq : word 1 of `eq'
if "`type'" == "row" {
mat `m' = `m'[1,"`eq':"]
/* mat coleq `m' = _: */
}
else {
mat `m' = `m'["`eq':", "`eq':"]
/* mat coleq `m' = _: */
/* mat roweq `m' = _: */
}
end
program define SkipEqs /* row|mat matname eq_skip_list */
args type M skiplst
local eqnames : coleq `M'
local eqnames : list uniq eqnames
tempname T
local curk 0
foreach eq of local eqnames {
local unused : subinstr local skiplst "`eq'" "`eq'" , ///
word count(local count)
if `count' == 0 {
if "`type'" == "mat" {
if `curk' > 0 {
mat `T' = nullmat(`T'), /*
*/ `M'[1..`curk', "`eq':"] \ /*
*/ `M'["`eq':", 1..`curk'] , /*
*/ `M'["`eq':", "`eq':"]
}
else {
mat `T' = `M'["`eq':", "`eq':"]
}
local curk = colsof(`T')
}
else {
mat `T' = nullmat(`T') , `M'[1, "`eq':"]
}
local skipped 1
}
}
if "`skipped'" != "" {
mat `M' = `T'
}
end
program define Mlist, sclass
sreturn clear
args list
gettoken thing1 0 : list , parse(":")
while "`thing1'" != "" {
IsThing integer number `thing1'
gettoken colon 0 : 0 , parse(" ,:")
IsToken : `colon'
gettoken thing2 0 : 0, parse(" ,")
IsThing integer number `thing2'
local opt1 "`opt1' `thing1'"
local opt2 "`opt2' `thing2'"
gettoken thing1 0 : 0, parse(",:")
if "`thing1'"== "," {
gettoken thing1 0 : 0, parse(":")
}
}
sreturn local opt1 "`opt1'"
sreturn local opt2 "`opt2'"
end
program define IsToken
args exp opt
if "`exp'" != "`opt'" {
dis as err "\``opt'' found where \``exp'' expected"
exit 198
}
end
program define IsThing
args type1 type2 opt
confirm `type1' `type2' `opt'
end
/*
Select equations to be included in the matrix
*/
program define Select /* b V select_list */
args b V list
tempname T
/* selection */
local enames : coleq `b'
local senames : list uniq enames
local num : word count `senames'
if `num' == 0 {
local i 1
while `i' <= colsof(`b') {
local neweq "`neweq' comp1"
local ++i
}
}
else {
tokenize "`senames'"
forvalues i = 1/`num' {
local junk : subinstr local list "`i'" "`i'", /*
*/ word count(local count)
if `count' == 0 {
SkipEqs row `b' "``i''"
SkipEqs mat `V' "``i''"
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -