*! tobexog V1.1.3 C F Baum 0216 * Ref: Smith and Blundell, Econometrica 54:3, 679-686 program define tobexog, rclass version 6.0 * parsing code and subroutines taken from -ivreg- 5.0.4 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'"=="" { exit 198 } local end`n' `end`n'' `p' gettoken p lhs : lhs, parse(" =") } tsunab end`n' : `end`n'' tsunab exog`n' : `lhs' } else { local exog `exog' `lhs' } gettoken lhs 0 : 0, parse(" ,[") match(paren) IsStop `lhs' } local 0 `"`lhs' `0'"' tsunab exog : `exog' tokenize `exog' local lhs "`1'" local 1 " " local exog `*' * NJC suggested code to handle either/both required options * problem: ll or ul is sufficient by itself; must accept them as well * ROC guidance in handling weights syntax [if] [in] [aw fw] [,ll(str) ul(str) *] local wtype `weight' local wtexp "`exp'" if "`weight'" != "" { local wgt `"[`weight' `exp']"' } local trunc="" if "`ll'" != "" { local trunc "ll(`ll')" } else if index(" `options' ", " ll ") { local trunc "ll" } if "`ul'" != "" { local trunc "`trunc' ul(`ul')" } else if index(" `options' ", " ul ") { local trunc "`trunc' ul" } if "`trunc'" == "" { di in r "must specify either ll( ) or ul( ) or both" exit 198 } marksample touse markout `touse' `lhs' `exog' `exog1' `end1' Subtract newexog : "`exog1'" "`exog'" local endo_ct : word count `end1' local ex_ct : word count `newexog' if `endo_ct' > `ex_ct' { di in red "equation not identified; must have at " /* */ "least as many instruments not in" di in red "the model as there are " /* */ "instrumented variables" exit 481 } * qui predict tokenize `end1' local rhadd " " local i 1 while "``i''" != "" { qui regress ``i'' `exog' `newexog' `wgt' if `touse' tempvar v_`i' qui predict `v_`i'',r * 0216: syntax per dmexog local rhadd `rhadd' `v_`i'' local i = `i' + 1 } local insts `exog' `newexog' qui tobit `lhs' `end1' `exog' `rhadd' `wgt' if `touse', `trunc' qui test `rhadd' return scalar df = r(df) return scalar df_r = r(df_r) return scalar tobexog = r(F) return scalar p = r(p) di in gr _n "Smith-Blundell test of exogeneity: " /* */ in ye %9.0g return(tobexog) in gr /* */ in gr " F(" %2.0f in ye return(df) "," return(df_r) /* */ in gr ") P-value = " in ye %6.0g return(p) 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 /* 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 exit