*! ivreg2 1.0.27 02Nov2002
*! authors cfb & mes
*! cloned from official ivreg version 5.0.9 19Dec2001
* 1.0.2: add logic for reg3. Sargan test
* 1.0.3: add prunelist to ensure that count of excluded exogeneous is correct
* 1.0.4: revise option to exog(), allow included exog to be specified as well
* 1.0.5: switch from reg3 to regress, many options and output changes
* 1.0.6: fixed treatment of nocons in Sargan and C-stat, and corrected problems
* relating to use of nocons combined with a constant as an IV
* 1.0.7: first option reports F-test of excluded exogenous; prunelist bug fix
* 1.0.8: dropped prunelist and switched to housekeeping of variable lists
* 1.0.9: added collinearity checks; C-stat calculated with recursive call;
* added ffirst option to report only F-test of excluded exogenous
* from 1st stage regressions
* 1.0.10: 1st stage regressions also report partial R2 of excluded exogenous
* 1.0.11: complete rewrite of collinearity approach - no longer uses calls to
* _rmcoll, does not track specific variables dropped; prunelist removed
* 1.0.12: reorganised display code and saved results to enable -replay()-
* 1.0.13: -robust- and -cluster- now imply -small-
* 1.0.14: fixed hascons bug; removed ivreg predict fn (it didn't work); allowed
* robust and cluster with z stats and correct dofs
* 1.0.15: implemented robust Sargan stat; changed to only F-stat, removed chi-sq;
* removed exog option (only orthog works)
* 1.0.16: added clusterised Sargan stat; robust Sargan handles collinearities;
* predict now works with standard SE options plus resids; fixed orthog()
* so it accepts time series operators etc.
* 1.0.17: fixed handling of weights. fw, aw, pw & iw all accepted.
* 1.0.18: fixed bug in robust Sargan code relating to time series variables.
* 1.0.19: fixed bugs in reporting ranks of X'X and Z'Z
* fixed bug in reporting presence of constant
* 1.0.20: added GMM option and replaced robust Sargan with (equivalent) J;
* added saved statistics of 1st stage regressions
* 1.0.21: added Cragg HOLS estimator, including allowing empty endog list;
* -regress- syntax now not allowed; revised code searching for "_cons"
* 1.0.22: modified cluster output message; fixed bug in replay for Sargan/Hansen stat;
* exactly identified Sargan/Hansen now exactly zero and p-value not saved as e();
* cluster multiplier changed to 1 (from buggy multiplier), in keeping with
* eg Wooldridge 2002 p. 193.
* 1.0.23: fixed orthog option to prevent abort when restricted equation is underid.
* 1.0.24: fixed bug if 1st stage regressions yielded missing values for saving in e().
* 1.0.25: Added Shea version of partial R2
* 1.0.26: Replaced Shea algorithm with Godfrey algorithm
* 1.0.27: Main call to regress is OLS form if OLS or HOLS is specified; error variance
* in Sargan and C statistics use small-sample adjustment if -small- option is
* specified; dfn of S matrix now correctly divided by sample size
*
* Variable naming:
* lhs = LHS endogenous
* endo = RHS endogenous (instrumented)
* inexog = included exogenous (instruments)
* exexog = excluded exogenous (instruments)
* iv = {inexog exexog} = all instruments
* rhs = {endo inexog} = RHS regressors
* 1 at the end of the name means the original varlist before duplicates and
* collinearities removed
program define ivreg2, eclass byable(recall)
version 7.0
local version 01.0.27
if replay() {
if `"`e(cmd)'"' != "ivreg2" { error 301 }
else {
syntax [, Level(integer $S_level) NOHEader NOFOoter /*
*/ EForm(string) PLUS]
if "`eform'"!="" {
local efopt "eform(`eform')"
}
}
}
else {
local n 0
gettoken lhs 0 : 0, parse(" ,[") match(paren)
IsStop `lhs'
if `s(stop)' { error 198 }
while `s(stop)'==0 {
if "`paren'"=="(" {
local n = `n' + 1
if `n'>1 {
capture noi error 198
di in red `"syntax is "(all instrumented variables = instrument variables)""'
exit 198
}
gettoken p lhs : lhs, parse(" =")
while "`p'"!="=" {
if "`p'"=="" {
capture noi error 198
di in red `"syntax is "(all instrumented variables = instrument variables)""'
di in red `"the equal sign "=" is required"'
exit 198
}
local endo`n' `endo`n'' `p'
gettoken p lhs : lhs, parse(" =")
}
* To enable Cragg HOLS estimator, allow for empty endo1 list
if "`endo1'" != "" {
tsunab endo`n' : `endo`n''
}
tsunab exexog`n' : `lhs'
}
else {
local inexog1 `inexog1' `lhs'
}
gettoken lhs 0 : 0, parse(" ,[") match(paren)
IsStop `lhs'
}
local 0 `"`lhs' `0'"'
if "`endo1'`inexog1'"=="" {
di in red "no regressors specified"
exit 102
}
if "`endo1'`exexog1'"=="" {
di in red "too few variables specified"
exit 102
}
tsunab inexog1 : `inexog1'
tokenize `inexog1'
local lhs "`1'"
local 1 " "
local inexog1 `*'
syntax [if] [in] [aw fw pw iw] [, /*
*/ FIRST FFIRST SMall Beta Robust CLuster(varname) hc2 hc3 /*
*/ GMM WMATRIX(string) ORTHOG(string) NOConstant Hascons /*
*/ Level(integer $S_level) NOHEader NOFOoter /*
*/ DEPname(string) EForm(string) PLUS *]
if "`orthog'" != "" {
tsunab orthog : `orthog'
}
if "`hc2'`hc3'" != "" {
if "`hc2'"!="" {
di in red "option `hc2' invalid"
}
else
di in red "option `hc3' invalid"
exit 198
}
if "`beta'" != "" {
di in red "option `beta' invalid"
exit 198
}
* Weights
* fweight and aweight accepted as is
* iweight not allowed with robust or gmm and requires a trap below when used with summarize
* pweight is equivalent to aweight + robust
if "`weight'" == "fweight" | "`weight'"=="aweight" {
local wgt `"[`weight'`exp']"'
}
if "`weight'" == "iweight" {
if "`robust'`cluster'`gmm'" !="" {
di in red "iweights not allowed with robust or gmm"
exit 101
}
else {
local wgt `"[`weight'`exp']"'
}
}
if "`weight'" == "pweight" {
local wgt `"[aweight`exp']"'
local robust "robust"
}
marksample touse
markout `touse' `lhs' `inexog1' `exexog1' `endo1' `cluster', strok
local insts1 `inexog1' `exexog1'
local rhs1 `endo1' `inexog1'
local iv1_ct : word count `insts1'
local rhs1_ct : word count `rhs1'
local endo1_ct : word count `endo1'
* Quick check; see also regress "bug" below
if `rhs1_ct' > `iv1_ct' {
di in red "equation not identified; must have at " /*
*/ "least as many instruments not in"
di in red "the regression as there are " /*
*/ "instrumented variables"
exit 481
}
* If depname not provided (default) name is lhs variable
if "`cluster'"!="" {
local clopt "cluster(`cluster')"
}
if "`eform'"!="" {
local efopt "eform(`eform')"
}
if "`depname'"=="" {
local depname `lhs'
}
*********** Main call to regress ***************
* A "bug" in regress means that if the system is identified after removal
* of collinearities but appears unidentified by counting variables
* before removal, regress will refuse to estimate.
* If no included endogenous vars, call using OLS syntax.
if `endo1_ct' > 0 {
quietly regress `lhs' `rhs1' (`insts1') if `touse' `wgt', /*
*/ `noconstant' `hascons' `options' `robust' `clopt'
}
else {
quietly regress `lhs' `rhs1' if `touse' `wgt', /*
*/ `noconstant' `hascons' `options' `robust' `clopt'
}
************************************************
if "`first'`ffirst'" != "" & (`endo1_ct' > 0) {
* For Godfrey method of Shea partial R2, need IV and OLS estimates without robust vces
tempname olsV ivV godfrey ols_s2 iv_s2 sols siv vrat godfrey ivest
if "`robust'`clopt'" == "" {
mat `ivV' = e(V)
scalar iv_s2 = e(rmse)^2
}
else {
estimates hold ivest
quietly regress `lhs' `rhs1' (`insts1') /*
*/ if `touse' `wgt', `noconstant' `hascons' /*
*/ `options'
mat `ivV' = e(V)
scalar iv_s2 = e(rmse)^2
estimates unhold ivest
}
estimates hold ivest
qui regress `lhs' `rhs1' /*
*/ if `touse' `wgt', `noconstant' `hascons' /*
*/ `options'
mat `olsV' = e(V)
scalar ols_s2 = e(rmse)^2
estimates unhold ivest
scalar vrat = iv_s2/ols_s2
mat `godfrey' = J(1,`endo1_ct',0)
mat colnames `godfrey' = `endo1'
mat rownames `godfrey' = "sheapr2"
local i 1
foreach w of local endo1 {
mat `sols'=`olsV'["`w'","`w'"]
mat `siv'=`ivV'["`w'","`w'"]
mat `godfrey'[1,`i'] = vrat*`sols'[1,1]/`siv'[1,1]
local i = `i'+1
}
}
tempvar iota y2
tempname ivresid Nprec ysum yy yyc r2u r2c b V ivest
qui predict double `ivresid' if `touse', resid
qui gen `iota'=1
qui gen double `y2'=`lhs'^2
* Stata summarize won't work with iweights, so must use matrix cross-product
qui matrix vecaccum `ysum' = `iota' `y2' `lhs' `wgt' if `touse'
* Nprec is ob count from mat accum. Use this rather than `N' in calculations
* here and below because `N' is rounded if iweights are used.
scalar `Nprec'=`ysum'[1,3]
scalar `yy'=`ysum'[1,1]
scalar `yyc'=`yy'-`ysum'[1,2]^2/`Nprec'
* Store results of IV regress
local N=e(N)
if "`cluster'"!="" {
local N_clust=e(N_clust)
}
local df_m=e(df_m)
local df_r=e(df_r)
tempname r2 r2_a rss mss rmse F
scalar `r2'=e(r2)
scalar `r2_a'=e(r2_a)
scalar `rss'=e(rss)
scalar `mss'=e(mss)
scalar `rmse'=e(rmse)
scalar `F'=e(F)
if "`gmm'`robust'`cluster'" != "" {
tempname S Sinv Ztu A XZ XZa XZb ZY B1 B V uZWZu j
tempvar gresid gresid2 yhat
* Bread of the sandwich
qui mat vecaccum `Ztu'=`ivresid' `exexog1' `inexog1' /*
*/ `wgt' if `touse', `noconstant'
* Optimal weighting matrix
* If user-supplied wmatrix is used, use it, otherwise use _robust (hence weights allowed)
if "`wmatrix'" != "" {
matrix `Sinv'=`wmatrix'
}
else {
* Has same results as mat accum `S'=`exexog1' `inexog1' [iweight=`ivresid'^2]
* Create identity matrix with correct col/row names
mat `S'=I(colsof(`Ztu'))+0*diag(`Ztu')
_robust `ivresid' `wgt' if `touse', variance(`S') `clopt' minus(0)
* Above doesn't work properly with iweights (i.e. yield same matrix as fw),
* hence iweight trap at start
mat `S'=`S'*1/`Nprec'
mat `Sinv'=syminv(`S')
}
* Generate cross-products of y, X, Z
qui matrix accum `A' = `lhs' `endo1' `exexog1' `inexog1' /*
*/ if `touse', `noconstant'
if "`noconstant'"=="" {
matrix rownames `A' = `lhs' `endo1' `exexog1' /*
*/ `inexog1' _cons
matrix colnames `A' = `lhs' `endo1' `exexog1' /*
*/ `inexog1' _cons
}
else {
matrix rownames `A' = `lhs' `endo1' `exexog1' `inexog1'
matrix colnames `A' = `lhs' `endo1' `exexog1' `inexog1'
}
if `endo1_ct' > 0 {
* X'Z is [endo1 inexog1]'[exexog1 inexog1]
mat `XZ'=`A'[2..`endo1_ct'+1,`endo1_ct'+2...]
* Append portion corresponding to included exog if they (incl constant) exist
if 2+`endo1_ct'+`iv1_ct'-(`rhs1_ct'-`endo1_ct') /*
*/ <= rowsof(`A') {
mat `XZ'=`XZ' \ /*
*/ `A'[2+`endo1_ct'+`iv1_ct'- /*
*/ (`rhs1_ct'-`endo1_ct')..., /*
*/ `endo1_ct'+2...]
}
mat `ZY'=`A'[`endo1_ct'+2...,1]
}
else {
* Cragg HOLS estimator with no endogenous variables
mat `XZ'= `A'[2+`iv1_ct'-(`rhs1_ct'-`endo1_ct')..., /*
*/ 2...]
mat `ZY'=`A'[2...,1]
}
mat `B1'=syminv(`XZ'*`Sinv'*`XZ'')
mat `B'=(`B1'*`XZ'*`Sinv'*`ZY')'
mat `V' = syminv(`XZ'*`Sinv'*`XZ'')*`Nprec'
* Rank of Z'Z is same as rank of S=Z'ee'Z
local iv_ct = rowsof(`Sinv') - diag0cnt(`Sinv')
* Save IV estimates if only J is needed
if "`gmm'"=="" {estimates hold `ivest'}
est post `B' `V'
qui _predict double `yhat', xb
qui gen double `gresid'=`lhs'-`yhat'
qui gen double `gresid2'=`gresid'^2
* J statistic
qui mat vecaccum `Ztu'=`gresid' `exexog1' `inexog1' /*
*/ `wgt' if `touse', `noconstant'
mat `uZWZu'= `Ztu'*`Sinv'*`Ztu'' * 1/`Nprec'
scalar `j' = `uZWZu'[1,1]
* Restore iv estimates if only J was needed, otherwise calc new R2s
if "`gmm'"=="" {estimates unhold `ivest'}
else {
qui matrix vecaccum `ysum' = `iota' `gresid2' /*
*/ `wgt' if `touse', `noconstant'
scalar `rss'= `ysum'[1,1]
if "`noconstant'"=="" {
scalar `mss'=`yyc'-`rss' }
else {
scalar `mss'=`yy'-`rss'
}
}
}
matrix `b'=e(b)
matrix `V'=e(V)
* Counts modified to include constant if appropriate
if "`noconstant'"=="" {
local iv1_ct = `iv1_ct' + 1
local rhs1_ct = `rhs1_ct' + 1
}
* Correct count of rhs variables accounting for dropped collinear vars
* Count includes constant
* Will take account of extraneous _cons (with zero coeff) if hascons
local rhs_ct=colsof(`b')
local i 1
while `i' <= colsof(`b') {
if `b'[1,`i']==0 {
local rhs_ct = `rhs_ct'-1
}
local i = `i'+1
}
* Now do small sample correction for GMM var-cov matrix.
* Stata's IV with robust has a small sample correction to the var-cov matrix
* so do the same for the GMM var-cov matrix. Corrections are exactly Stata's
* corrections at this point (see removal of small sample corrections below).
if "`gmm'" != "" {
if "`cluster'"=="" {
matrix `V'=`V'*`Nprec'/(`Nprec'-`rhs_ct')
}
else {
matrix `V'=`V'*(`Nprec'-1)/(`Nprec'-`rhs_ct') /*
*/ * `N_clust'/(`N_clust'-1)
}
}
scalar `r2u'=1-`rss'/`yy'
scalar `r2c'=1-`rss'/`yyc'
if "`gmm'" != "" {
if "`noconstant'"=="" {
scalar `r2'=`r2c'
scalar `r2_a'=1-(1-`r2')*(`Nprec'-1)/(`Nprec'-`rhs_ct')
}
else {
scalar `r2'=`r2u'
scalar `r2_a'=1-(1-`r2')*`Nprec'/(`Nprec'-`rhs_ct')
}
}
* hascons code - check if true/false
* Strip out extraneous _cons in last col if hascons true
* Report error if hascons false and reset macro to empty string
* True if _cons in last column and coeff==0, false if !=0
if "`hascons'"!="" {
local cn : colnames `b'
local cn : subinstr local cn "_cons" "_cons" , word count(local hc)
if `hc' == 1 {
if `b'[1,colsof(`b')]==0 {
matrix `b'=`b'[1,1..colsof(`b')-1]
matrix `V'=`V'[1..rowsof(`V')-1,1..colsof(`V')-1]
}
else {
di in gr "nb: hascons false"
local hascons ""
}
}
}
* Sargan statistic if overid, J if robust or GMM
* Error variance in denominator uses small adjustment if -small- option specified.
* Code also calculates correct count of instruments (including constant)
* after possible collinearities => dropped instruments
if "`robust'`cluster'`gmm'" == "" {
tempname ZZ Ztu ZZinv uZWZu sargan sargmse sarganp
if "`small'" == "" {
scalar `sargmse'=`rss'/`Nprec'
}
else {
scalar `sargmse'=`rss'/(`Nprec'-`rhs_ct')
}
qui mat accum `ZZ' = `insts1' `wgt' if `touse', `noconstant'
qui mat vecaccum `Ztu' = `ivresid' `insts1' `wgt' /*
*/ if `touse', `noconstant'
matrix `ZZinv' = syminv(`ZZ')
mat `uZWZu' = `Ztu'*`ZZinv'*`Ztu''
local iv_ct = rowsof(`ZZ') - diag0cnt(`ZZinv')
local sargandf = `iv_ct' - `rhs_ct'
if `sargandf' == 0 {
scalar `sargan' = 0
}
else {
scalar `sargan' = `uZWZu'[1,1]/`sargmse'
scalar `sarganp' = chiprob(`sargandf',`sargan')
}
}
else {
tempname jp
local jdf = `iv_ct' - `rhs_ct'
if `jdf' == 0 {
scalar `j' = 0
}
else {
scalar `jp' = chiprob(`jdf',`j')
}
}
* orthog option: C statistic (difference of Sargan statistics)
if "`orthog'"!="" {
* Initialize cstat
local cstat 0
* Each variable listed must be in instrument list.
* To avoid overwriting, use cendo, cinexog1, cexexog, cendo_ct, cex_ct
local cendo1 "`endo1'"
local cinexog1 "`inexog1'"
local cexexog1 "`exexog1'"
local cinsts1 "`insts1'"
local crhs1 "`rhs1'"
local clist1 "`orthog'"
local clist_ct : word count `clist1'
* Check to see if c-stat vars are in original list of all ivs
* cinexog1 and cexexog1 are after c-stat exog list vars have been removed
* cendo1 is endo1 after included exog being tested has been added
foreach x of local clist1 {
local llex_ct : word count `cexexog1'
Subtract cexexog1 : "`cexexog1'" "`x'"
local cex1_ct : word count `cexexog1'
local ok = `llex_ct' - `cex1_ct'
if (`ok'==0) {
* Not in excluded, check included and add to endog list if it appears
local llin_ct : word count `cinexog1'
Subtract cinexog1 : "`cinexog1'" "`x'"
local cin1_ct : word count `cinexog1'
local ok = `llin_ct' - `cin1_ct'
if (`ok'==0) {
* Not in either list
di in r "Error: `x' listed in orthog() but does not appear as exogenous."
error 198
}
else {
local cendo1 "`cendo1' `x'"
}
}
}
* If robust or GMM, create optimal weighting matrix to pass to ivreg2
* by extracting the submatrix from the full S and then inverting.
* This guarantees the C stat will be non-negative. See Hayashi (2000), p. 220.
if "`robust'`cluster'`gmm'" != "" {
tempname CSa CS CSinv
if "`noconstant'" !="" {
local cexin "`cexexog1' `cinexog1'"
}
else {
local cexin "`cexexog1' `cinexog1' _cons"
}
local v1 1
foreach x of local cexin {
if `v1'==1 {
mat `CSa' = `S'[`"`x'"',.]
local v1 0
}
else {
mat `CSa' = `CSa' \ `S'[`"`x'"',.]
}
}
local v1 1
foreach x of local cexin {
if `v1'==1 {
mat `CS' = `CSa'[.,`"`x'"']
local v1 0
}
else {
mat `CS' = `CS', `CSa'[.,`"`x'"']
}
}
mat `CSinv'=syminv(`CS')
}
* Calculate C statistic with recursive call to ivreg2
* Collinearities may cause problems, hence -capture-.
capture {
tempname csargan cj cstat cstatp cj
estimates hold `ivest', restore
if "`robust'`cluster'`gmm'" == "" {
capture ivreg2 `lhs' `cinexog1' /*
*/ (`cendo1'=`cexexog1') if `touse' /*
*/ `wgt', `noconstant' `hascons' /*
*/ `small' `options'
local rc = _rc
if `rc' == 481 {
local cstat = 0
local cstatdf = 0
}
else {
* Use MSE from original Sargan test to ensure p.d.
scalar `csargan'=e(sargan)*e(rss)/`rss'
local csargdf=e(sargandf)
scalar `cstat' = `sargan' - `csargan'
local cstatdf = `sargandf' - `csargdf'
}
}
else {
capture ivreg2 `lhs' `cinexog1' /*
*/ (`cendo1'=`cexexog1') /*
*/ if `touse' `wgt', `noconstant' /*
*/ `hascons' `small' `options' `robust' /*
*/ `clopt' `gmm' wmatrix("`CSinv'")
local rc = _rc
if `rc' == 481 {
local cstat = 0
local cstatdf = 0
}
else {
scalar `cj'=e(j)
local cjdf=e(jdf)
scalar `cstat' = `j' - `cj'
local cstatdf = `jdf' - `cjdf'
}
}
estimates unhold `ivest'
scalar `cstatp'= chiprob(`cstatdf',`cstat')
* Collinearities may cause C-stat dof to differ from the number of variables in orthog()
* If so, set cstat=0
if `cstatdf' != `clist_ct' {
local cstat = 0
}
}
}
* Check if adequate number of observations and clusters
if `N' <= `iv_ct' {
di in r "Error: number of observations must be greater than number of instruments"
di in r " including constant."
error 2001
}
if "`cluster'" != "" {
if `N_clust' <= `iv_ct' {
if "`gmm'" != "" {
di in r "Error: number of clusters insufficient to calculate optimal weighting matrix"
error 498
}
else {
* Need to caculate correct rank of Z'Z matrix = # of IVs
qui _rmcoll `insts1' if `touse', `noconstant'
local iv_ct : word count `r(varlist)'
if "`noconstant'"=="" {
local iv_ct = `iv_ct' + 1
}
* Re-check if adequate number of observations using correct rank of Z'Z
if `N' <= `iv_ct' {
di in r "Error: number of observations must be greater than number of instruments"
di in r " including constant."
error 2001
}
* VCV matrix, J, F stat, and C stat (if present) all meaningless
mat `V'=e(V)*0
scalar `j' = .
scalar `F' = .
if "`orthog'"!="" { `cstat' = . }
}
}
}
* First stage regression option
* Code here because it relies on proper count of (non-collinear) IVs
* generated earlier
* Note that nocons option + constant in instrument list means first-stage
* regressions are reported with nocons option. First-stage F-stat therefore
* correctly includes the constant as an explanatory variable.
if ("`first'`ffirst'"!="") & (`endo1_ct' > 0) {
tempname firstmat sheapr2 pr2 pr2F pr2p
di in gr _newline "First-stage regressions"
di in smcl in gr "{hline 23}"
if `iv1_ct' > `iv_ct' {
di in gr "Warning: collinearities detected among instruments"
di in gr "1st stage tests of excluded exogenous variables may be incorrect"
}
di
doFirst "`endo1'" "`inexog1'" "`exexog1'" /*
*/ `touse' `"`wgt'"' `"`noconstant'"' `"`ffirst'"'
capture mat `firstmat'=`godfrey' \ r(firstmat)
if _rc==0 {
di in gr "Summary results for first-stage regressions:"
di
di in gr " Shea"
di in gr _c "Variable Partial R2 Partial R2 F("
di in gr %3.0f `firstmat'[4,1] "," %6.0f `firstmat'[5,1] ") P-value"
local i = 1
local nrvars : word count `endo1'
while `i' <= `nrvars' {
local vn : word `i' of `endo1'
scalar `sheapr2'=`firstmat'[1,`i']
scalar `pr2'=`firstmat'[2,`i']
scalar `pr2F'=`firstmat'[3,`i']
scalar `pr2p'=`firstmat'[6,`i']
di in y %-12s "`vn'" _col(15) %8.4f `sheapr2' _col(31) %8.4f `pr2' /*
*/ _col(49) %8.2f `pr2F' _col(64) %8.4f `pr2p'
local i = `i' + 1
}
di
}
else {
di in ye "Warning: missing values encountered; first stage regression results not saved"
}
}
* Post results
* If robust, the finite sample correction is N/(N-K), and with no small
* we change this to 1 (a la Davidson & MacKinnon 1993, p. 554, HC0).
* If cluster, the finite sample correction is (N-1)/(N-K)*M/(M-1), and with no small
* we change this to 1 (a la Wooldridge 2002, p. 193), where M=number of clusters.
* In the adj of the V matrix for non-small, we use Nprec instead of N because
* iweights rounds off N. Note that iweights are not allowed with robust
* but the robust section uses Nprec anyway to maintain consistency of code.
local NminusK = `N'-`rhs_ct'
if "`small'"!="" {
est post `b' `V', dep(`depname') obs(`N') esample(`touse') /*
*/ dof(`NminusK')
}
else {
* Remove finite sample corrections
if "`cluster'"=="" {
matrix `V'=`V'*(`Nprec'-`rhs_ct')/`Nprec'
scalar `rmse'=sqrt(`rss'/`Nprec')
}
else {
matrix `V'=`V'*(`Nprec'-`rhs_ct')/(`Nprec'-1) /*
*/ * (`N_clust'-1)/`N_clust'
scalar `rmse'=sqrt(`rss'/`Nprec')
}
est post `b' `V', dep(`depname') obs(`N') esample(`touse')
}
if "`gmm'"=="" {
est scalar F=`F'
est scalar p=Ftail(`df_m',`df_r',`F')
est scalar Fdf2=`df_r'
}
else {
est matrix W `Sinv'
}
if "`small'"!="" {
est scalar df_r=`df_r'
est local small "small"
}
if "`cluster'"!="" {
est scalar N_clust=`N_clust'
est local clustvar `cluster'
}
if "`robust'`cluster'`gmm'" != "" {
estimates local vcetype "Robust"
}
est scalar df_m=`df_m'
est scalar r2=`r2'
est scalar rmse=`rmse'
est scalar rss=`rss'
est scalar mss=`mss'
est scalar r2_a=`r2_a'
est scalar yy=`yy'
est scalar yyc=`yyc'
est scalar r2u=`r2u'
est scalar r2c=`r2c'
est scalar rankzz=`iv_ct'
est scalar rankxx=`rhs_ct'
if "`gmm'`robust'`cluster'"=="" {
est scalar sargan=`sargan'
if `sargan' != 0 & `sargan' != . {
est scalar sarganp=`sarganp'
est scalar sargandf=`sargandf'
}
}
else {
est scalar j=`j'
if `j' != 0 & `j' != . {
est scalar jp=`jp'
est scalar jdf=`jdf'
}
}
if "`orthog'"!="" {
est scalar cstat=`cstat'
if `cstat'!=0 & `cstat' != . {
est scalar cstatp=`cstatp'
est scalar cstatdf=`cstatdf'
est local clist `clist1'
}
}
if "`first'`ffirst'" != "" & `endo1_ct'>0 {
* Capture here because firstmat empty if mvs encountered in 1st stage regressions
capture est matrix first `firstmat'
}
est local depvar `lhs'
if "`gmm'"=="" {
if "`endo1'" == "" {
est local model "ols"
}
else {
est local model "iv"
}
}
else {
est local model "gmm"
}
if `"`exp'"' != "" {
est local wexp "`exp'"
est local wtype `weight'
}
est local cmd ivreg2
est local version `version'
if "`noconstant'`hascons'"!="" {est scalar cons=0}
else {est scalar cons=1}
est local instd `endo1'
est local insts `insts1'
est local predict "ivreg2_p"
}
***************************************************************
* Display results
* Prepare for insuff # of clusters problem
* Macro `clustprob' is either "1" (problem) or "0" or "" (no problem)
capture local clustprob = string(e(N_clust) <= e(rankzz))
if "`noheader'"=="" {
if "`e(model)'"=="gmm" {
if "`e(instd)'"=="" {
di in gr _n "HOLS-GMM estimation"
di in gr "{hline 19}"
}
else {
di in gr _n "GMM estimation"
di in gr "{hline 14}"
}
}
else {
if "`e(instd)'"=="" {
if "`robust'"!="" | "`cluster'"!="" {
di in gr _n "OLS regression with robust standard errors"
di in gr "{hline 42}"
}
else {
di in gr _n "Ordinary Least Squares (OLS) regression"
di in gr "{hline 39}"
}
}
else {
if "`robust'"!="" | "`cluster'"!="" {
di in gr _n "IV (2SLS) regression with robust standard errors"
di in gr "{hline 48}"
}
else {
di in gr _n "Instrumental variables (2SLS) regression"
di in gr "{hline 40}"
}
}
}
di
if "`e(clustvar)'"!="" {
di in gr "Number of clusters (" "`e(clustvar)'" ") = " in ye %-4.0f e(N_clust) _continue
}
else {
di in gr " " _continue
}
di in gr _col(55) "Number of obs = " in ye %8.0f e(N)
local Fdf1=e(df_m)
if "`e(clustvar)'"=="" {
local Fdf2=e(N)-e(rankzz)
}
else {
local Fdf2=e(N_clust)-1
}
* No Stata-generated F stat for GMM, or if insuff # of clusters problem
if "`e(model)'" != "gmm" & "`clustprob'" != "1" {
di in gr _col(55) "F(" %3.0f `Fdf1' "," %6.0f `Fdf2' ") = " in ye %8.2f e(F)
di in gr _col(55) "Prob > F = " in ye %8.4f e(p)
}
di in gr "Total (centered) SS = " in ye %12.0g e(yyc) _continue
di in gr _col(55) "Centered R2 = " in ye %8.4f e(r2c)
di in gr "Total (uncentered) SS = " in ye %12.0g e(yy) _continue
di in gr _col(55) "Uncentered R2 = " in ye %8.4f e(r2u)
di in gr "Residual SS = " in ye %12.0g e(rss) _continue
di in gr _col(55) "Root MSE = " in ye %8.1g e(rmse)
di
}
* Display coefficients etc.
* Unfortunate but necessary hack here: to suppress message about cluster adjustment of
* standard error, clear e(clustvar) and then reset it after display
local cluster `e(clustvar)'
est local clustvar
est di, `plus' `efopt' level(`level')
est local clustvar `cluster'
* Display footer
if "`nofooter'"=="" {
* Report either (a) Sargan-Hansen-C stats, or (b) insufficient # of clusters problem
if "`clustprob'" == "0" | "`clustprob'" == "" {
* Display Sargan-Hansen statistic
if "`e(vcetype)'" == "Robust" {
if "`e(instd)'" != "" {
di in gr _c "Hansen J statistic (overidentification test of all instruments): "
}
else {
di in gr _c "Hansen J statistic (Lagrange mulitplier test of excluded instruments): "
}
di in ye _col(72) %7.3f e(j)
local overiddf e(jdf)
local overidp e(jp)
}
else {
if "`e(instd)'" != "" {
di in gr _c "Sargan statistic (overidentification test of all instruments): "
}
else {
di in gr _c "Sargan statistic (Lagrange mulitplier test of excluded instruments): "
}
di in ye _col(72) %7.3f e(sargan)
local overiddf e(sargandf)
local overidp e(sarganp)
}
if e(rankxx) < e(rankzz) {
di in gr _col(52) "Chi-sq(" in ye `overiddf' /*
*/ in gr ") P-val = " in ye _col(72) %6.5f `overidp'
}
else {
di in gr _col(50) "(equation exactly identified)"
}
* Display orthog option: C statistic (difference of Sargan statistics)
if e(cstat) != . {
* If C-stat = 0 then warn, otherwise output
if e(cstat) > 0 {
di in gr _c "C statistic (exogeneity/orthogonality of specified instruments): "
di in ye _col(73) %6.3f e(cstat)
di in gr _col(52) "Chi-sq(" in ye e(cstatdf) /*
*/ in gr ") P-val = " in ye _col(72) %6.5f e(cstatp)
di in gr "Instruments tested: `e(clist)'"
}
if e(cstat) == 0 {
di in gr _n "Collinearity/identification problems in restricted equation:"
di in gr " C statistic not calculated for orthog option"
}
}
}
else {
di in r "Warning: insufficient number of clusters to calculate robust var-cov matrix."
di in r " Test statistics not reported."
}
di in smcl in gr "{hline 78}"
* Warn about dropped instruments if any
* (Re-)calculate number of user-supplied instruments
local iv1_ct : word count `e(insts)'
local iv1_ct = `iv1_ct' + `e(cons)'
if `iv1_ct' > e(rankzz) {
di in gr "Collinearities detected among instruments: " _c
di in gr `iv1_ct'-e(rankzz) " instrument(s) dropped"
}
if "`e(instd)'" != "" {
di in gr "Instrumented: " _c
Disp `e(instd)'
}
di in gr "Instruments: " _c
Disp `e(insts)'
di in smcl in gr "{hline 78}"
}
end
program define IsStop, sclass
/* sic, must do tests one-at-a-time,
* 0, may be very large */
if `"`0'"' == "[" {
sret local stop 1
exit
}
if `"`0'"' == "," {
sret local stop 1
exit
}
if `"`0'"' == "if" {
sret local stop 1
exit
}
if `"`0'"' == "in" {
sret local stop 1
exit
}
if `"`0'"' == "" {
sret local stop 1
exit
}
else
sret local stop 0
end
program define Disp
local first ""
local piece : piece 1 64 of `"`0'"'
local i 1
while "`piece'" != "" {
di in gr "`first'`piece'"
local first " "
local i = `i' + 1
local piece : piece `i' 64 of `"`0'"'
}
if `i'==1 { di }
end
* Performs first-stage regressions
* Modified by MES to produce an F-test of the excluded instruments
program define doFirst, rclass /* /*
*/ */
args
endog /* variable list (including depvar)
*/ inexog /* list of included exogenous
*/ exexog /* list of excluded exogenous
*/ touse /* touse sample
*/ weight /* full weight expression w/ []
*/ nocons /* noconstant option
*/ ffirst /* display f-stat only */
tokenize `endog'
tempname statmat statmat1
local i 1
while "``i''" != "" {
* di in gr "First-stage regression of ``i'':"
if "`ffirst'" != "" {
quietly regress ``i'' `inexog' `exexog' `weight' /*
*/ if `touse', `nocons'
}
else {
di in gr "First-stage regression of ``i'':"
regress ``i'' `inexog' `exexog' `weight' if `touse', `nocons'
}
tempvar y2 iota xhat
tempname ysum yy rssall rssinc pr2 F p
quietly predict double `xhat' if `touse', xb
local endoghat "`endoghat' `xhat'"
quietly test `exexog'
scalar `F'=r(F)
scalar `p'=r(p)
local df=r(df)
local df_r=r(df_r)
scalar `rssall'=e(rss)
qui gen double `y2'=``i''^2
* Stata summarize won't work with iweights, so must use matrix cross-product
qui gen `iota'=1
qui matrix vecaccum `ysum' = `iota' `y2' `weight' if `touse', noconstant
scalar `yy'=`ysum'[1,1]
* 1st stage regression without excluded exogenous
quietly regress ``i'' `inexog' `weight' if `touse', `nocons'
scalar `rssinc'=e(rss)
* NB: uncentered R2 for main regression is 1-rssall/yy; for restricted is 1-rssinc/yy;
* squared semipartial correlation=(rssinc-rssall)/yy=diff of 2 R2s
* Squared partial correlation (="partialled-out R2")
scalar `pr2'=(`rssinc'-`rssall')/`rssinc'
if "`ffirst'" == "" {
di in gr "Partial R-squared of excluded instruments: " _c
di in ye %8.4f `pr2'
di in gr "Test of excluded instruments:"
di in gr " F(" %3.0f `df' "," %6.0f `df_r' ") = " in ye %8.2f `F'
di in gr " Prob > F = " in ye %8.4f `p'
di
}
capture {
mat `statmat1' = (`pr2' \ `F' \ `df' \ `df_r' \ `p')
mat colname `statmat1' = ``i''
if `i'==1 {mat `statmat'=`statmat1'}
else {mat `statmat' = `statmat' , `statmat1'}
}
local i = `i' + 1
}
capture mat rowname `statmat' = pr2 F df df_r pvalue
if _rc==0 {
return matrix firstmat `statmat'
}
end
* Remove all tokens in dirt from full
* Returns "cleaned" full list in cleaned
program define Subtract /* : */
args
cleaned /* macro name to hold cleaned list
*/ colon
/* ":"
*/ full
/* list to be cleaned
*/ dirt
/* tokens to be cleaned from full */
tokenize `dirt'
local i 1
while "``i''" != "" {
local full : subinstr local full "``i''" "", word all
local i = `i' + 1
}
tokenize `full'
/* cleans up extra spaces */
c_local `cleaned' `*'
end
本文档为【ivreg2 1】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。