**********************************************************************
Attached below are the following ado files:
reg3.ado
And help files:
reg3.hlp
**********************************************************************
reg3.ado
Instructions for use: Cut out the following program and put it in a
file called "reg3.ado". Be sure that the file is saved as a plain
text (ASCII) file and that it has a hard return at the end of the
last line in the file.
Put reg3.ado in your C:\ADO directory (you may have to create this
directory) or your Stata working directory (i.e., your current directory).
Note: Do not put it in the C:\STATA\ADO directory. Only official Stata
ado and hlp files should be placed in this directory.
For more information, see [2] ado in Vol. 1 of the Reference manuals.
---------------------------------cut here---start-of-reg3.ado-------
*! version 1.0.5 24oct1997 IDEAS distribution
program define reg3
version 5.0
local options "Level(integer $S_level) noConstant"
parse "`*'", parse(",")
if "`1'" == "" | "`1'" == "," {
if "$S_E_cmd" != "reg3" {
error 301
}
parse "`*'"
}
else {
/* Parse (y1 x1 x2) (y2 y1 x2 x3) structure.
* Pick up full varlist (flist), y-array (y`i'), left-hand
* sides (lhslist) , equation names (eqnm`i')
*/
local flist
local enlist
local inlist
local eqlist /* kept 2 ways */
local lhslist
local neq = 0
parse "`*'", parse("() [],")
IsKey `1'
while $S_1 == 0 {
if "`1'" == "(" {
local list
mac shift
while "`1'" != ")" & "`1'" != "" {
local list `list' `1'
mac shift
}
if "`1'" != ")" {
dis in red _quote ")" _quote "missing from equation"
exit 198
}
local neq = `neq' + 1
unabbrev `list', min(1)
local eqn`neq' $S_1
if $S_2 == 1 {
eq `eqn`neq'' :
}
else { eq `eqn`neq'' }
}
else {
/* We should have an equation name here */
eq ? `1'
local k : word count $S_1
if `k' < 1 {
dis in red "Expect an equation here: `1'"
exit 198
}
local neq = `neq' + 1
local eqn`neq' $S_1
local eqnm`neq' `1'
local eqlist `eqlist' `1'
}
local flist `flist' `eqn`neq''
local endog1 : word 1 of `eqn`neq''
local lhslist `lhslist' `endog1'
local y`neq' `endog1'
if ("`eqnm`neq''" == "" ) {
Subtract "`eqlist'" "`endog1'"
if "$S_2" != "" {
local eqnm`neq' = substr("`neq'`endog1'", 1, 8)
}
else { local eqnm`neq' `endog1' }
local eqlist `eqlist' `eqnm`neq''
}
mac shift
IsKey `1'
}
DropDup `lhslist'
/* Full parse, process options */
local options "`options' 2sls 3sls Allexog CONstraints(string) " /*
*/ "CORr(string) DFK EXog(string) First ENdog(string) " /*
*/ "INst(string) ITerate(int 500) IReg3 Mvreg noLOG " /*
*/ "Ols SMall SUre TOLerance(real 1e-6) TRace"
local if "opt"
local in "opt"
parse "`*'"
/* Process the estimation method options */
local method = trim("`2sls' `3sls' `ols' `sure' `mvreg'")
local i : word count `method'
if ( `i' > 1 ) {
disp in red "Cannot specify more that one estimation method: `method'"
exit 198
}
else if "`method'" == "" {
local method = "3sls"
}
if "`method'" == "`ols'" | "`method'" == "mvreg" | "`method'" == "2sls" {
local corr = "independent"
local dfk = "dfk"
local small = "small"
}
if "`method'" == "`ols'" | "`method'" == "mvreg" | /*
*/ "`method'" == "sure" {
local allexog = "allexog"
}
/* Process some options and implied settings */
if `iterate' != 500 { local ireg3 = "ireg3" }
if "`log'" == "nolog" { local log = "quietly"
}
else { local log = "noisily" }
if "`trace'" == "trace" { local trace = "noisily"
}
else { local trace = "quietly" }
local cons
if "`constan'" != "noconstant" { local cons "_cons" }
setCorr "`corr'"
local corr "$S_1"
/* Errors in command */
if "`inst'" != "" & ("`endog'" != "" | "`exog'" != "") {
dis in red "Cannot specify an instrument list with an " /*
*/ "exogenous or endogenous list."
exit 198
}
/* Process exog list and endog lists. Full endogenous list
(may exceed number of left-hand sides. */
DropDup "`flist'"
local flist $S_1
if "`allexog'" == "allexog" {
local exlist "`flist'"
}
else {
if "`inst'" == "" {
Subtract "`endog'" "`flist'"
if "$S_1" != "" {
dis in blue "Warning additional endogenous variables not " /*
*/ "in the system"
dis in blue "have no effect and are ignored: $S_1"
}
/* Allow an exogenous over-ride of endogenous variables */
Subtract "`lhslist'" "`exog'"
local enlist $S_1 `endog'
DropDup `enlist'
local enlist $S_1
Subtract "`exog'" "`enlist'"
if "$S_2" != "" {
dis in red "Cannot specify variables as both endogenous and " /*
*/ "exogenous: $S_2"
exit 198
}
local flist `flist' `exog'
DropDup `flist'
local flist $S_1
/* No endog-exog matches, safe to assume all non-endog are exog */
Subtract "`flist'" "`enlist'"
local exlist $S_1
}
else {
DropDup `inst'
local exlist $S_1
local flist `flist' `inst'
DropDup `flist'
local flist $S_1
Subtract "`flist'" "`exlist'"
local enlist $S_1
}
}
/* Set obs to use */
tempvar touse
mark `touse' `if' `in' [`weight'`exp']
markout `touse' `enlist' `exlist'
qui count if `touse'
local t = _result(1)
local nex : word count `exlist'
if `t' <= `nex' { noi error 2001 }
/* Process information about equations. Set up temporary storage. */
tempname DF
mat `DF' = I(`neq')
local matcols
local coleq
local reslist
local i 1
while `i' <= `neq' {
local k`i' : word count `eqn`i''
local k`i' = `k`i'' - ("`cons'" == "")
if `k`i'' > `t' { noi error 2001 }
testIdnt "`eqn`i''" "`exlist'"
/* Residual vars and list for 2nd stage. */
tempvar res`i'
local reslist `reslist' `res`i''
/* Build matrix column and equation name lists */
Hack `eqn`i''
local matcols `matcols' $S_1 `cons'
local j 1
while `j' <= `k`i'' {
local coleq `coleq' `eqnm`i''
local j = `j' + 1
}
* Matrix of denominators for residual covariance of 2nd stage
if "`dfk'" == "dfk" {
local j 1
while `j' <= `i' {
mat `DF'[`i',`j'] = 1 / sqrt((`t' - `k`i'') * (`t' - `k`j''))
if `i' != `j' { mat `DF'[`j', `i'] = `DF'[`i', `j'] }
local j = `j' + 1
}
}
else {
local df_adj = 1 / `t'
}
local i = `i' + 1
}
/* Perform OLS to get the instrumental estimates of the Y's (or
* all non-exogenous terms). Build a list of instrument names (it
* is aligned with enlist. */
if "`first'" != "" {
dis in gr _newline "First-stage Regression Estimates"
dis in gr "--------------------------------"
local show1 = "noi"
}
parse "`enlist'", parse(" ")
local i 1
while "``i''" != "" {
cap `show1' reg ``i'' `exlist' if `touse' [`weight'`exp'], `constan'
if _rc != 0 {
dis in red "1st stage failure."
dis in red "Equation: ``i'' `exlist'"
exit _rc
}
tempvar iv`i'
local inlist `inlist' `iv`i''
qui predict double `iv`i'' if `touse'
local i = `i' + 1
}
/* Form the xvar lists with the instrumental variables in place
* of the endogenous variables.
*/
tempvar one
g byte `one' = 1
local i 1
while `i' <= `neq' {
Subst "`eqn`i''" "`enlist'" "`inlist'"
if "`constan'" == "noconstant" {
local eqni`i' $S_1
}
else {
local eqni`i' "$S_1 `one'"
}
local i = `i' + 1
}
/*
* Disturbance matrix ==> (B, VCE) ==> Disturbance matrix loop
* Acts like a do ... while
*/
tempname EpE EpEi EpEiB D V b bhold
tempname sZpZ Zpy sZpy ZpZ ZpyS sigma
local iterate = max(1, `iterate')
local done 0
local itcnt 0
while !`done' {
/* Get the inverse covariance matrix of errors. */
/* On first pass, just get the 2SLS/OLS cov. matrix */
if `itcnt' == 0 {
mat `EpE' = I(`neq')
}
else {
qui mat accum `EpE' = `reslist' if `touse' [`weight'`exp'], nocons
}
mat rowname `EpE' = `lhslist'
mat colnames `EpE' = `lhslist'
cap drop `reslist'
if "`dfk'" == "dfk" {
mElMult "`EpE'" "`DF'"
}
else {
mat `EpE' = `EpE' * `df_adj'
}
mat `EpEi' = `EpE'
mat `EpEi' = syminv(`EpE')
if "`corr'" == "independent" {
mat `D' = vecdiag(`EpE')
mat `EpEiB' = diag(`D')
mat `EpEiB' = syminv(`EpEiB')
}
else {
mat `EpEiB' = `EpEi'
}
chkDiag "`EpEiB'"
/* Get the Covariance matrix of the 3SLS estimator. We build it
* in pieces extracting only portions of the Z_1'Z_2 accumulated
* matrices for each equation pair. Get the (EpEi (X) I) y too.
* The latter is built separately looping over the full row
* and column combinations to avoid extra storage and bookeeping.
* Could make this a bit faster by using the Z_1'Z_1 and Z_n'Z_n
* computed with the 2nd and next to last accums.
*/
local ktot : word count `matcols'
mat `sZpZ' = J(`ktot', `ktot', 0)
cap { mat drop `sZpy' }
local at_i 1
local i 1
while `i' <= `neq' {
local frm = `k`i'' + 1
mat `ZpyS' = J(1, `k`i'', 0)
local at_j 1
local j 1
while `j' <= `neq' {
scalar `sigma' = `EpEiB'[`i',`j']
/* Get Cov. matrix. */
if `j' <= `i' {
qui mat accum `ZpZ' = `eqni`i'' `eqni`j'' if `touse' /*
*/ [`weight'`exp'], noconstant
mat `ZpZ' = `ZpZ'[1..`k`i'',`frm'...]
mat `ZpZ' = `ZpZ' * `sigma'
mat subst `sZpZ'[`at_i',`at_j'] = `ZpZ'
if `i' != `j' {
mat `ZpZ' = `ZpZ' '
mat subst `sZpZ'[`at_j',`at_i'] = `ZpZ'
}
}
/* Get sum(sigma Z_i y_j) */
mat vecaccum `Zpy' = `y`j'' `eqni`i'' if `touse' /*
*/ [`weight'`exp'], noconstant
mat `Zpy' = `Zpy' * `sigma'
mat `ZpyS' = `ZpyS' + `Zpy'
local at_j = `at_j' + `k`j''
local j = `j' + 1
}
/* Build (EpEiB (X) I) y */
mat `ZpyS' = `ZpyS' '
mat `sZpy' = `sZpy' \ `ZpyS'
local at_i = `at_i' + `k`i''
local i = `i' + 1
}
/* Get variance-covariance matrix and vector of coefficents.
* Post results.
*/
mat `V' = syminv(`sZpZ')
mat `b' = `V' * `sZpy'
mat `b' = `b''
mat rownames `V' = `matcols'
mat roweq `V' = `coleq'
mat colnames `V' = `matcols'
mat coleq `V' = `coleq'
mat colnames `b' = `matcols'
mat coleq `b' = `coleq'
if "`small'" == "small" {
local tdof = `t' - `k1' + ("`cons'" != "")
mat post `b' `V', dof(`tdof')
}
else {
local tdof = `t'
mat post `b' `V', obs(`t')
}
/* Apply constraints */
if "`constra'" != "" { Constrn "`constra'" "`small'" "`tdof'" }
mat `b' = get(_b)
if `itcnt' == 0 { mat `bhold' = 2 * `b' }
local rdiff = mreldif(`b', `bhold')
mat `bhold' = `b'
/* Evaluate stopping conditions */
if ("`ireg3'" != "ireg3" & `itcnt' != 0) | `itcnt' >= `iterate' | /*
*/ `rdiff' < `toleran' {
local done 1
}
else {
/* Get new residual vectors for error covariance matrix */
local i 1
parse "`lhslist'", parse(" ")
while "``i''" != "" {
qui predict double `res`i'', eq(`eqnm`i''), if `touse'
qui replace `res`i'' = ``i'' - `res`i''
local i = `i' + 1
}
}
if "`ireg3'" == "ireg3" & `itcnt' > 0 {
`log' disp in gr "Iteration `itcnt': " /*
*/ "Maximum coefficient change = " in ye %10.7g `rdiff'
`trace' mat list `b'
}
local itcnt = `itcnt' + 1
} /* end while -- iteration loop */
/* Equation summary statistics and retained globals */
global S_E_eqns ""
tempvar errs
local i 1
while `i' <= `neq' {
if `k`i'' > 1 {
qui test [`eqnm`i'']
}
else { qui test [`eqnm`i'']_cons }
global S_E_c`i' = _result(6)
if "`small'" == "small" {
global S_E_p`i' = fprob(_result(3), _result(5), _result(6))
}
else {
global S_E_p`i' = chiprob(_result(3), _result(6))
}
qui predict `errs', eq(`eqnm`i''), if `touse'
qui replace `errs' = (`y`i''- `errs') * (`y`i'' - `errs')
qui sum `errs' if `touse'
local mse = _result(3)
global S_E_m`i' = sqrt(_result(3))
if "`small'" == "small" {
global S_E_m`i' = sqrt(_result(3)*_result(1) / (`t' - `k`i''))
}
qui sum `y`i'' if `touse'
global S_E_r`i' = 1 - `mse' / (_result(4) * (`t'-1) / `t')
global S_E_k`i' = `k`i'' - ("`cons'" != "")
global S_E_eqns $S_E_eqns `eqnm`i''
drop `errs'
local i = `i' + 1
}
mat S_E_sig = `EpEi'
mat S_E_corr = corr(`EpEi')
parse "`lhslist'", parse(" ")
global S_E_depv `*'
parse "`exlist'", parse(" ")
global S_E_exog `*'
parse "`enlist'", parse(" ")
global S_E_endg `*'
global S_E_cons `cons' /* undocumented, only for cert */
global S_E_cns `constra'
global S_E_dft "`dfk'"
global S_E_nobs `t'
global S_E_neq `neq'
global S_E_cor "`corr'"
global S_E_sml "`small'"
global S_E_iter "`ireg3'"
global S_E_meth "`method'"
global S_E_cmd "reg3"
}
/* Display results */
local testtyp " Chi2"
if "$S_E_sml" == "small" { local testtyp "F-Stat" }
local method "Three-stage"
if "$S_E_meth" == "ols" | "$S_E_meth" == "mvreg" {
local method "Multivariate"
}
if "$S_E_meth" == "2sls" { local method "Two-stage" }
if "$S_E_meth" == "sure" { local method = "Seemingly Unrelated" }
dis ""
if "$S_E_iter" != "" { dis in ye "Iterated " _c }
dis in gr "`method' Least Squares Regression Estimates"
if "$S_E_cns" != "" {
disp in gr _newline "Constraints:"
matrix dispCns
}
dis in gr _dup(66) "-"
dis in gr "Equation Obs Parms RMSE " /*
*/ _quote "R-sq" _quote " `testtyp' P"
dis in gr _dup(66) "-"
parse "$S_E_eqns", parse(" ")
local i 1
while "``i''" != "" {
dis in ye " ``i''" _col(11) %7.0f $S_E_nobs %7.0f ${S_E_k`i'} /*
*/ " " %9.0g ${S_E_m`i'} %10.4f ${S_E_r`i'} " " %9.2g /*
*/ ${S_E_c`i'} %9.4f ${S_E_p`i'}
local i = `i' + 1
}
matrix mlout, level(`level')
DispVars "Endogenous variables: " "$S_E_endg" 2 6 78
DispVars "Exogenous variables: " "$S_E_exog" 3 6 78
dis in gr _dup(78) "-"
end
program define IsKey
if "`1'"=="[" | "`1'"=="]" | "`1'"=="if" | "`1'"=="in" | /*
*/ "`1'"=="" | "`1'"=="," {
global S_1 1
}
else { global S_1 0 }
end
/* Drop all duplicate tokens from list */
program define DropDup /* */
parse "`*'", parse(" ")
local i 1
while "``i''" != "" {
local j = `i' + 1
while "``j''" != "" {
if "``j''" == "``i''" {
local `j' " "
}
local j = `j' + 1
}
local i = `i' + 1
}
global S_1 `*'
end
/* Remove all tokens in elist from flist */
* Returns "cleaned" flist in S_1 and dropped tokens in S_2 */
program define Subtract /* */
local flist `1'
local elist `2'
global S_2
local nendog : word count `elist'
parse "`flist'", parse(" ")
local i 1
while "``i''" != "" {
local j 1
while `j' <= `nendog' {
local endog : word `j' of `elist'
local j = `j' + 1
if "`endog'" == "``i''" {
global S_2 $S_2 ``i''
local `i' " "
local j = `nendog' + 1 /* simulate a c-style continue */
}
}
local i = `i' + 1
}
global S_1 `*'
end
/* Find all occurances beyond the first token in List of tokens
* in FindList and replace with corresponding token from SubsList
* Assumes FindList and SubstList have same number of elements.
* For the current use, hacks off the first token. */
program define Subst /* */
local list `1'
local fndList `2'
local subList `3'
local ntoks : word count `fndList'
parse "`list'", parse(" ")
local 1 " "
local i 2
while "``i''" != "" {
local j 1
while `j' <= `ntoks' {
local findw : word `j' of `fndList'
if "`findw'" == "``i''" {
local subst : word `j' of `subList'
local `i' `subst'
}
local j = `j' + 1
}
local i = `i' + 1
}
global S_1 `*'
end
/* Hack off the first element of a macro and return the result in S_1. */
program define Hack /* */
parse "`*'", parse(" ")
mac shift
global S_1 `*'
end
/* Set disturbance covariance matrix structure */
program define setCorr /* */
local corr "`1'"
global S_1
local corrs "unstructured independent"
local corrn "1 1"
if ("`corr'" == "") {
global S_1 : word 1 of `corrs'
exit
}
local numopt : word count `corrs'
local i 1
while `i' <= `numopt' {
local corropt : word `i' of `corrs'
local minlen : word `i' of `corrn'
if substr("`corropt'", 1, max(`minlen', length("`corr'"))) == "`corr'" {
global S_1 "`corropt'"
exit
}
local i = `i' + 1
}
dis in red "Unsupported disturbance correlation option: `corr'"
exit 198
end
/* Test if equation is identified -- order condition */
program define testIdnt /* */
local eqn `1'
local exlist `2'
Hack "`eqn'"
local rhs $S_1
Subtract "`rhs'" "`exlist'"
local excnt : word count `exlist'
local endcnt : word count `rhs'
if `endcnt' > `excnt' {
dis in red "Equation is not identified -- does not meet order conditions"
dis in red "Equation: `eqn'"
dis in red "Exogenous variables: `exlist'"
exit 471
}
end
/* Display a list of variables breaking line nicely */
program define DispVars /* */
local prefix `1' /* prefix string for first line */
local varlist `2' /* variable list */
local space `3' /* cols of space after prefix */
local strtcol `4' /* starting column for all lines but first */
local maxlen `5'
disp in gr "`prefix'" _c
disp _col(`space') _c
local curlen = length("`prefix'") + `space'
parse "`varlist'", parse(" ")
local i = 1
while "``i''" != "" {
local len = length("``i''")
if (`curlen' + `len' + 1) > `maxlen' {
disp ""
disp _col(`strtcol') _c
local curlen `strtcol'
}
disp in gr "``i'' " _c
local curlen = `curlen' + `len' + 1
local i = `i' + 1
}
disp ""
end
/* Element-by-element matrix multiplication. Result left in */
program define mElMult /* */
local mat1 `1'
local mat2 `2'
local rows = rowsof(`mat1')
local cols = colsof(`mat1')
if `rows' != rowsof(`mat2') | `cols' != colsof(`mat2') { exit 503 }
local i 1
while `i' <= `rows' {
local j 1
while `j' <= `cols' {
mat `mat1'[`i', `j'] = `mat1'[`i', `j'] * `mat2'[`i', `j']
local j = `j' + 1
}
local i = `i' + 1
}
end
/* Check the diagonal of a matrix for missings */
program define chkDiag /* */
local mat `1'
local dim = rowsof(`mat')
if `dim' != colsof(`mat') { exit 503 }
local i 1
while `i' <= `dim' {
if `mat'[`i',`i'] == 0 {
dis in red "Covariance matrix of errors is singular"
mat list `mat'
exit 506
}
local i = `i' + 1
}
end
/* Apply constraints to the system */
program define Constrn /* */
local constr `1'
local small `2' /* non-blank ==> t-stat, not z-stat */
local dof `3'
tempname A beta C I IAR j k r R a Vbeta b V
matrix makeCns `constr'
matrix `C' = get(Cns)
matrix `b' = get(_b)
matrix `V' = get(VCE)
local cdim = colsof(`C')
local cdim1 = `cdim' - 1
matrix `R' = `C'[.,1..`cdim1']
matrix `r' = `C'[.,`cdim']
matrix `A' = `V'*`R''
matrix `A' = `R'*`A'
matrix `A' = syminv(`A')
scalar `j' = 1
while `j' <= rowsof(`A') {
if `A'[`j',`j'] == 0 { error 412 }
scalar `j' = `j' + 1
}
matrix `A' = `R'' * `A'
matrix `A' = `V' * `A'
matrix `IAR' = `A' * `R'
local vdim = colsof(`V')
matrix `I' = I(`vdim')
matrix `IAR' = `I' - `IAR'
matrix `a' = `r'' * `A''
matrix `beta' = `b' * `IAR''
matrix `beta' = `beta' + `a'
matrix `Vbeta' = `V' * `IAR''
matrix `Vbeta' = `IAR' * `Vbeta'
if "`small'" == "small" {
mat post `beta' `Vbeta' `C', dof(`dof')
}
else {
mat post `beta' `Vbeta' `C', obs(`dof')
}
end
exit
- Requires double storage for the total number of endogenous variables
(left hand side or otherwise) + double storage for the errors from each
equation.
- Currently contraints are tested after the first stage. This is
a matter of convenience, since the full model has not been constructed until
that point. However, it could cause some wasted time if the specified
constraints are invalid for the model.
- Due to the way constraints are applied, constrained models cannot be
estimated if the unconstrained model is not identified and has sufficient
data.
---------------------------------cut here---end-of-reg3.ado---------
**********************************************************************
reg3.hlp
Instructions for use: Cut out the following program and put it in a
file called "reg3.hlp". Be sure that the file is saved as a plain
text (ASCII) file and that it has a hard return at the end of the
last line in the file.
Put reg3.hlp in your C:\ADO directory (you may have to create this
directory) or your Stata working directory (i.e., your current directory).
Note: Do not put it in the C:\STATA\ADO directory. Only official Stata
ado and hlp files should be placed in this directory.
For more information, see [2] ado in Vol. 1 of the Reference manuals.
---------------------------------cut here---start-of-reg3.hlp-------
.-
help for ^reg3^ (IDEAS distribution 24oct1997)
.-
Estimate a system of equations by three-stage least squares
-----------------------------------------------------------
^reg3^ ^(^depvar1 varlist^) (^depvar2 varlist^)^ ... [^if^ exp] [^in^ range]
[^, noc^onstant ^l^evel^(^#^)^ ^ex^og^(^varnames^) en^dog^(^varnames^)^
^in^st^(^varlist^)^ ^a^llexog ^con^straints^(^clist^)^ ^ir^eg3 ^dfk^ ^f^irst ^sm^all
{ ^o^ls | ^m^vreg | ^su^re | ^2sls^ | ^3sls^ } ^cor^r^(^correlation^)^
maximize_options ]
--or--
^reg3^ eqname1 eqname2 [...] [^if^ exp] [^in^ range] [^,^ same_options]
^reg3^ shares the features of all estimation commands; see help @est@.
To reset problem-size limits, see help @matsize@.
Description
-----------
^reg3^ estimates a system of structural equations, where some equations contain
endogenous variables among the explanatory variables. Estimation is via
three-stage least squares (Zellner and Theil, 1962). Typically, the
endogenous explanatory variables are dependent variables from other equations
in the system.
Nomenclature
------------
A ^structural equation^ is defined as one of the equations specified in the
system. ^Dependent variable^ will have its usual interpretation as the
left-hand side variable in an equation. All dependent variables are
explicitly ^endogenous^ to the system and as such are treated as correlated
with the disturbances in the system equations. Unless specified in an
^endog()^ option, all other variables in the system are treated as ^exogenous^
to the system and uncorrelated with the disturbances. The exogenous variables
are used to construct ^instruments^ for the endogenous variables.
Options
-------
^noconstant^ suppresses the constant terms. ^reg3^ takes a rather high-handed
approach toward the ^noconstant^ option. When specified, no constants are
used in any of the equations or in the first or second stage estimations.
With this option, the user should add a variable containing all ones to
any equations requiring a constant.
^exog(^varlist^)^ specifies additional exogenous variables that are not
included in any of the system equations. This can occur when there are
identities in the system which are not estimated. If implicitly
exogenous variables from the equations are listed here, that's okay;
^reg3^ will just ignore the additional information. Specified variables
will be added to the exogenous variables in the system and used in the
"first-stage" to develop the instruments for the endogenous variables. By
specifying dependent variables from the structural equations, ^exog()^ can
be used to override their endogeneity and produce seemingly unrelated
regression (^sureg^) results.
^endog(^varlist^)^ identifies variables in the system which are not dependent
variables, but are endogenous to the system. These variables must appear
in the varlist of at least one equation in the system. Again, the need
for this identification often occurs when there are identities. For
example, a variable that is the sum of an exogenous variable and a
dependent variable may appear as an explanatory variable in some
equations.
^inst(^varlist^)^ specifies a full list of all exogenous variables and may
not be used with the ^endog()^ or ^exog()^ options. It must contain a full
list of variables to be used in computing the instruments. Like ^exog()^,
the list may contain variables not specified in the system of equations.
This option can be used to achieve the same results as the ^endog()^ and
^exog()^ options and the choice is a matter of convenience. Any variable
not specified in the varlist is assumed to be endogenous to the system.
As with ^exog()^, including the dependent variables from the structural
equations will override their endogeneity and produce seemingly
unrelated regressions (^sureg^).
^allexog^ indicates that all right-hand-side (rhs) variables are to be
treated as exogenous -- even if they appear as the left-hand-side (lhs) of
another equation in the system. This option can be used to enforce a
seemingly unrelated regression or multivariate regression estimation even
when some lhs variables appear as regressors.
^ireg3^ causes -reg3- to iterate over the estimated disturbance covariance
matrix and parameter estimates until the parameter estimates converge.
Under seemingly unrelated regression, this iteration converges to the
maximum likelihood results.
^constraints(^clist^)^ specifies the constraint numbers of the constraints to
be applied to the system. In addition to providing constraints for
three-stage least squares, the ^constraint^ option can be combined with
^exog()^, ^sure^, ^mvreg^ or explicitly independent equations to produce
constrained seemingly unrelated regression or constrained multivariate
regression. For examples of constraints with multiple equation
estimators, see help @mlogit@.
^ols^ causes ^reg3^ to perform equation-by-equation OLS on the system -- even
if dependent variables appear as regressors and/or the regressors differ
for each equation (see @mvreg@). ^ols^ implies ^allexog^, ^dfk^, ^small^,
and ^corr(independent)^.
^mvreg^ is equivalent to as ^ols^.
^sure^ causes ^reg3^ to perform a seemingly unrelated regression estimation
of the system -- even if dependent variables from some equations appear as
regressors in other equations (see @sureg@). ^sure^ is a synomym for
^allexog^.
^2sls^ causes ^reg3^ to perform equation-by-equation two stage least squares
on the full system of equations. This option implies ^dfk^, ^small^, and
^corr(independent)^.
^3sls^ specifies the full three-stage least square estimation of the system
and is the default for ^reg3^.
^dfk^ specifies the use of an alternate divisor in computing the covariance
matrix for the equation errors. As an asymptotically justified estimator,
^reg3^ by default uses the number of sample observations (n) as a divisor.
When the ^dfk^ option is set, the divisor is taken to be
sqrt((t - k_i) * (t - k_j)). Where k_i and k_j are the number of
parameters in equations i and j respectively.
^small^ specifies that small sample statistics are to be computed. It shifts
the test statistics from chi-square and z-statistics to F-statistics and
t-statistics. This option is primarily intended to support multivariate
regression. While the standard errors from each equation are computed
using the degrees of freedom for the equation, the degrees of freedom for
the t-statistics are all taken to be those for the first equation. This
will not usually pose a problem since multivariate regression is typically
applied when the regressors are the same across equations.
^first^ requests that the first-stage regression results be displayed.
^level(^#^)^ specifies the confidence level for the confidence intervals of the
coefficients; see help @level@.
^corr(^correlation^)^ specifies the assumed form of the correlation
structure of the equation disturbances and is rarely requested explicitly.
For the family of models estimated by ^reg3^ the only two allowable
correlation structures are ^i^ndependent and ^u^nstructured. The default
is ^unstructured^. This option is used almost exclusively to estimate a
system of equations by two-stage least squares or to perform least squares
regression with ^reg3^ on multiple equations. In these cases, the
correlation can be set to independent -- forcing ^reg3^ to treat the
covariance matrix of equation disturbances as diagonal in estimating model
parameters. Thus, a set of two-stage coefficient estimates can be
obtained if the system contains endogenous rhs variables. Alternately,
OLS regression can be imposed, even if the regressors differ across
equations. Without the ^independent^ option, ^reg3^ would estimated the
the latter by seemingly unrelated regressions. Note that any tests
performed after estimation with the independent option will treat
coefficients in different equations as having no covariance --
independent.
maximize_options control the iteration process when ^ireg3^ is specified;
see [R] maximize. You should never have to specify them.
Remarks
-------
^reg3^ estimates systems of structural equations where some equations contain
endogenous variables among the explanatory variables. Generally, these
endogenous variables are the dependent variables of other equations in the
system, though not always. The error term is correlated with the endogenous
variables - violating the assumptions of ordinary least squares. Further,
since some of the explanatory variables are the dependent variables of other
equations in the system, the error terms among the equations are expected to
be correlated. ^reg3^ uses an instrumental variable approach to produce
consistent estimates and generalized least squares (GLS) to account for the
correlation structure in the errors across the equations. Good general
references on three-stage include Kmenta (1971) and Greene (1993).
Conceptually, three-stage least squares can be thought of as producing
estimates from a three-step process.
1) In the first stage, instruments are developed for all endogenous variables.
These instruments can simply be considered as the predicted values
resulting from a regression of each endogenous variable on all exogenous
variables in the system.
2) In the second stage, consistent estimates are developed for the covariance
matrix of the equation errors. These estimates are based on the residuals
from a two-stage least squares estimation of each structural equation.
3) In the third stage, a GLS type estimation is performed using the covariance
matrix estimated in the second stage and with instruments in place of the
endogenous variables (on the right-hand side).
[Technical Note]
Under certain conditions when all equations are just identified, the
three-stage least squares estimates "fold-up" to the two-stage least squares
estimates available from ^reg^. This behavior is directly analogous to
^sureg^ producing the same results as as equation-by-equation ordinary least
squares when all of the equations in the system have the same independent
variables. Conceptually, the covariance of the errors in these cases adds no
additional information to the system. While we can estimate the covariance
matrix of the equation errors, this information simply "folds-up" in the final
estimates of the of the coefficients. However, as with ^sureg^, estimating an
exactly identified system with ^reg3^ can have advantages over
equation-by-equation two-stage. After ^reg3^, tests involving coefficients in
separate equations can be easily performed using ^test^.
Example - simple macro-economic model
-------------------------------------
A very simple macro economic model could be postulated that relates
consumption (consump) to private and government wages paid (wagepriv and
wagegovt). Simultaneously, private wages could be postulated to depend
on consumption, total government expenditures (govt) and the lagged stock of
capital in the economy (capital1). This model could be written
consump = B0 + B1*wagepriv + B2*wagegovt + e1
and
wagepriv = B3 + B4*consump + B5*govt + B6*capital1 + e2
Assuming this is the full system, consump and wagepriv will be endogenous
variables, with wagegovt, govt and capital1 exogenous. Using the first
version from the syntax diagram, this model could be estimated with
. ^reg3 (consump wagepriv wagegovt) (wagepriv consump govt capital1)^
Example - supply and demand
---------------------------
Some of the most common simultaneous systems encountered are supply and demand
models. A very simple system could be specified as
qDemand = B0 + B1*price + B2*pcompete + B3*income + e1
qSupply = B4 + B5*price + B6*praw + e2
Equilibrium condition: quantity = qDemand = qSupply
Where:
quantity - is the quantity of a product produced and sold
price - is the price of the product
pcompete - is the price of a competing product
income - is the average income level of consumers
praw - is the price of raw materials used to produce the product
This system could be estimated using the equation version of the ^reg3^ syntax
as
. ^eq qDemand : quantity price pcompete income^
. ^eq qSupply : quantity price praw^
. ^reg3 qDemand qSupply, endog(price)^
Note that we must specify price as endogenous since it does not appear as a
dependent variable.
Alternately, the model could use the parenthesis syntax.
. ^reg3 (quantity price pcompete income) (quantity price praw), exog(price)^
However, in this case, ^reg3^ will create unique equation names for the two
quantity equations. You may prefer to name the equations explicitly using
^eq^.
Example - Klein's model
-----------------------
Klein's (1941) model of the US economy is often used to demonstrate system
estimators . It contains several common features which will serve to
demonstrate the syntax of ^reg3^. The model is defined by
c = B0 + B1*p + B2*p1 + B3*w + e1 (1)
i = B4 + B5*p + B6*p1 + B7*k1 + e2 (2)
wp = B8 + B9*y + B10*y1 + B11*year + e3 (3)
y = c + i + g (4)
p = x - t - wp (5)
k = klag1 + i (6)
w = wg + wp (7)
The variables in the model are listed below.
+----+----------------------------------------+-------------+
| c | Consumption | endogenous |
| p | Private industry profits | endogenous |
| p1 | Last year's private industry profits | exogenous |
| wp | Private wage bill | endogenous |
| wg | Government wage bill | exogenous |
| w | Total wage bill | endogenous |
| i | Investment | endogenous |
| k1 | Lagged level of capital stock | exogenous |
| y | Total income/demand | endogenous |
| y1 | Last year's total income | exogenous |
| g | Government spending | exogenous |
| t | Indirect bus taxes + net exports | exogenous |
+----+----------------------------------------+-------------+
Equations (1)-(3) are behavioral and contain explicit disturbances (e1, e2,
e3). The remaining equations are identities which specify additional
variables in the system and their "accounting" relationships with the
variables in the behavioral equations. Some variables are explicitly
endogenous by appearing as dependent variables in Equations 1-3. Others are
implicitly endogenous as linear combinations which contain other endogenous
variables (e.g. wg, and p).
Using the equation syntax for ^reg^, Klein's model may be specified as
. ^eq c p p1 w^
. ^eq i p p1 k1^
. ^eq wp y y1 yr^
. ^reg3 c i wp, endog(w p y) exog(t wg g)^
We used the ^exog()^ option to identify t, wg, and g as exogenous variables in
the system. We need to identify these variables as they are part of the
system but do not directly appear in any of the behavioral equations.
Without this option, ^reg3^ would not know they were part of the system. The
^endog()^ option specifying w, p, and y is also required. Without this
information, ^reg3^ would be unaware these variables they are linear
combinations which include endogenous variables.
Rather than listing additional endogenous and exogenous variables, we could
specify the full list of exogenous variables...
. ^reg3 c i wp, inst(g t wg yr p1 k1 y1)^
or, equivalently
. ^local inlist "g t wg yr p1 k1 y1"^
. ^reg3 c i wp, inst(`inlist')^
Using the first syntax for ^reg3^, the system could be estimated by
. ^reg3 (c p p1 w) (i p p1 k1) (wp y y1 yr), endog(w p y) exog(t wg g)^
or
. ^reg3 (c p p1 w) (i p p1 k1) (wp y y1 yr), inst(g t wg yr p1 k1 y1)^
It is even possible to mix the equation and parenthesis syntax...
. ^reg3 c (i p p1 k1) wp, endog(w c i p y) exog(y1 t wg p1 g)^
or
. ^reg3 (c p p1 w) i (wp y y1 yr), endog(w p y) exog(t wg g)^
^reg3^ is tolerant of all combinations, and all of these commands will produce
identical output.
The variable names used above are traditional abbreviations from economics.
For non-economists, we could have specified the system using more generally
understood names, as below.
. ^eq consump profits profits1 wagetot^
. ^eq invest profits profits1 capital1^
. ^eq wagepriv totinc totinc1 year^
. ^local enlist "wagetot profits totinc"^
. ^local exlist "taxnetx wagegovt govt"^
. ^reg3 consump invest wagepriv, endog(`enlist') exog(`exlist')^
Example -- constraints
----------------------
As a simple example of constraints, Equation 1 above may be re-written with
both wages explicitly appearing (rather than as a variable containing the sum).
Using the longer names for the variables, we have
consump = B0 + B1*profits + B2*profits1 + B3*wagepriv + B12*wagegovt + e1
To retain the effect of the identity in Equation 7, we need B3=B12 as a
constraint on the system. We obtain this result by defining the constraint and
then specifying its use in ^reg3^. Since ^reg3^ is a system estimator, we will
need to use the full equation syntax of ^constraint^.
. ^eq consump profits profits1 wagepriv wagegovt^
. ^constraint define 1 [consump]wagepriv = [consump]wagegovt^
. ^reg3 consump invest wagepriv, endog(`enlist') exog(`exlist') constr(1)^
We can also impose constraints across the equations. For example, the
admittedly meaningless constraint of requiring profits to have the same effect
in both the consumption and investment equations could be imposed. Retaining
the constraint on the wage coefficients, we could type
. ^constraint define 2 [consump]profits = [invest]profits^
. ^reg3 consump invest wagepriv, endog(`enlist') exog(`exlist') constr(1-2)^
Example - two-stage least squares system
----------------------------------------
Klien's model could be estimated by two-stage least squares using ^reg3^.
. ^eq consump profits profits1 wagetot^
. ^eq invest profits profits1 capital1^
. ^eq wagepriv totinc totinc1 year^
. ^local enlist "wagetot profits totinc"^
. ^local exlist "taxnetx wagegovt govt"^
. ^reg3 consump invest wagepriv, endog(`enlist') exog(`exlist')^ ^2sls^
Example - constrained seemingly unrelated regression
----------------------------------------------------
We could have imposed a seemingly unrelated regression on the system --
thereby forcing ^reg3^ to ignore the rhs endogenous variables. Adding the
earlier constraints, this model could be estimated as
. ^constraint define 1 [consump]wagepriv = [consump]wagegovt^
. ^constraint define 2 [consump]profits = [invest]profits^
. ^reg3 consump invest wagepriv, endog(`enlist') exog(`exlist') sure^
> ^constr(1-2)^
Example - constrained multivariate regression
---------------------------------------------
We could estimate this same constrained system while forcing the ^reg3^ to
ignore the covariance among the equations.
. ^reg3 consump invest wagepriv, endog(`enlist') exog(`exlist') ols^
> ^constr(1-2)^
--or--
. ^reg3 consump invest wagepriv, endog(`enlist') exog(`exlist') mvreg^
> ^constr(1-2)^
If all of the equations have the same regressors and there are no endogenous
variables, the ^ols^ option is not required. The three-stage least square
esimtates will naturally "fold-up" to the multivariate regression estimates.
Using admittedly silly constraints on an admittedly silly system...
. ^eq consump profits profits1 wagetot^
. ^eq invest profits profits1 wagetot^
. ^eq wagepriv profits profits1 wagetot^
. ^constraint define 1 [consump]profits = [consump]profits1^
. ^constraint define 2 [consump]wagetot = [invest]wagetot^
. ^constraint define 3 [consump]wagetot = [wagepriv]wagetot^
. ^reg3 consump invest wagepriv, constr(1-2)^
Saved results
-------------
^S_E_cmd^ reg3
^S_E_meth^ method of estimation -- ols, mvreg, sure, 2sls, or 3sls
^S_E_neq^ number of equations
^S_E_c#^ chi-square statistic for equation #,
F-statistic if ^small^ specified
^S_E_dft^ Type of degree of freedom calculation "dfk" or ""
^S_E_p#^ prob > chi for equation # , prob > F with ^small^
^S_E_m#^ RMSE for equation #
^S_E_r#^ R-squared for equation #
^S_E_k#^ number of parameters for equation #
^S_E_sig^ the estimated covariance matrix of disturbances
^S_E_corr^ the estimated correlation matrix of disturbances
^S_E_depv^ list of the dependent variables
^S_E_exog^ list of the exogenous variables
^S_E_endg^ list of the endogenous variables
^S_E_eqns^ list of the equation names
^S_E_cns^ list of constraint numbers
^S_E_cor^ disturbance correlation structure for estimating coefficients
^S_E_sml^ "small" if small sample statistics are computed
^S_E_iter^ "ireg3" if disturbance covariance matrix and coefficient
estimates were iterated
^S_E_nobs^ number of observations in the estimation sample
Author
------
Vince Wiggins
StataCorp.
vwiggins@@stata.com
References
----------
Greene, W.H. 1993. "Econometric Analysis". 2nd ed. New York: Macmillan.
Kmenta, J. 1971. "Elements of Econometrics". Macmillan.
Zelner,A. and H. Theil. 1962. Three stage least Squares: simultaneous
estimate of simultaneous equations, "Econometrica", 29: 63-68.
Also see
--------
Manual: ^[U] 26 Estimation and post-estimation commands^
^[U] 35 Overview of model estimation^
On-line: help for @est@; @eq@, @lincom@, @predict@, @test@, @testnl@, @vce@,
@mvreg@, @sureg@, @reg@, @constraint@
---------------------------------cut here---end-of-reg3.hlp---------