********************************************************************** 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---------