*! version 1.2 1feb2025
help cfbinout

Title

cfbinout -- Control Function Estimation of Binary Outcome Models

Syntax

cfbinout link depvar [varlist1] (varlist2 = varlist_iv) [if] [in] [weight], [options]

Variables

depvar binary outcome variable

varlist1 exogenous explanatory variables

varlist2 endogenous explanatory variables

varlist_iv (excluded) instrumental variables

link

logit logit link

probit probit link

cloglog complementary log-log link

Options

Model
fslink(name) specify first-stage link function for endogenous dummy regressors; name may be linear, logit, or probit; logit is the default

fsswitch switch equation-wise to fslink(linear) in case of quasi-complete separation in first-stage

order(#) specify order of control-function polynomial; order(1) is the default

SE/Robust
vce(vcetype) vcetype may be oim, opg, robust, or cluster clustvar; oim is the default

terza(2017|2023) compute standard errors following Terza (2017) or Terza (2023); 2023 is the default

noanalytic calculate cross-stage derivatives numerically

Store/Generate
noresgenerate do not permanently save first-stage residuals; do not store and report control function coefficients

resname(stub) permanently save first-stage residual as stub_varname; the default for stub is res

replace replace stub_varname if already exists

fskeep keep full first-stage results

Reporting
level(#) set confidence level; default as set by set level

display_options as for ereturn display

Maximization
nosearch do not search for an optimal delta when numerically calculating second derivatives

maximization_options as for logit, probit, and cloglog

varlist1, varlist2, and varlist_iv may contain factor variables and time-series operators; see fvvarlist and tsvarlist.

Factor variables and and time-series operators are not allowed for depvar.

bootstrap is allowed, by and svy are not allowed; see [U] prefix.

pweights, fweights and iweights are allowed, with iweight being the default.

Depending on how the options for variance estimation are specified, the do-file _llcfbin_v.do may be required to be stored in the ado-path.

Postestimation commands, depending on the chosen link function, are largely the same as after logit, probit, and cloglog, respectively; see [R] logit postestimation.

Description

cfbinout implements control function (two-stage residuals inclusion) estimation of binary outcome models, specifically logit, probit, and cloglog, as suggested in Wooldridge (2015).
That is, in a first-stage the endogenous right-hand-side variables (varlist2) are regressed on the exogenous variables in the model (varlist1 and varlist_iv).
Subsequently, the (generalized) residuals from these regressions enter the second-stage regression as additional regressors.
Regarding the implementation in Stata and Mata, cfbinout draws on Terza (2017, 2023).
cfbinout complements the real Stata command ivprobit and the recent community contributed command ivcloglog.
Unlike ivprobit and ivcloglog, cfbinout allows for discrete/factor variables in varlist2.
For them, nonlinear first-stage models (default logit, alternatively probit) are estimated and generalized residuals are included in the second-stage regression, unless fslink(linear) is specified.
With link probit and fslink(linear), cfbinout probit is equivalent to ivprobit, twostep in terms of model estimation.
An important difference is, however, that unless the option noresgenerate is specified, cfbinout takes the control functions (included residuals) into account in postestimation;
see the discussion on Statalist.
The equivalence of cfbinout probit is even closer with cfprobit, an official Stata command that was released for StataNow almost at the same time as cfbinout was completed.

Options

Model

fslink(name) specifies a link function for first-stage regressions with binary left-hand-side variable.
The default is the fslink(logit) link, i.e. logit regressions are estimated in the first-stage for dummy endogenous regressors.
fslink(probit) provides an alternative nonlinear specification.
Specifying logit or probit as first-stage link function makes cfbinout use generalized residuals as auxiliary regressors in the second-stage.
(For logit, but not for probit, the generalized residual takes the simple form of the difference between the observed outcome and the fitted success probability.)
Note that cfbinout identifies binary variables even if no factor variables syntax is used.
With fslink(linear), cfbinout estimates linear regressions in the first-stage and uses conventional residuals as auxiliary regressors in the second-stage, regardless of whether the endogenous regressors are continuous or binary.
If varlist2 does not contain binary variables, specifying fslink(name) has no effect, since all first-stage regressions are linear anyway.

fsswitch allows cfbinout to estimate a linear first-stage although the respective endogenous regressor is binary and fslink(name) is not fslink(linear).
With fsswitch, cfbinout switches to a linear first-stage regression if the respective first-stage is subject to quasi-complete separation.
Without fsswitch, cfbinout will fail in such a case.

order(#) determines the order of the control-function polynomial. With order(1), which is the default, the (generalized) first-stage residuals enter the second-stage regression linearly.
With order(2), the first-stage residuals enter not only linearly but also as squared values.
With order(3), also cubic transformations of the first-stage residuals are considered as second-stage, rhs variables; ect.
Interactions of first-stage residuals (from different first-stage regressions) do not enter the second-stage, irrespective of how order(#) is specified.
Only strictly positive integer values are allowed.

SE/Robust

vce(vcetype) specifies the method used for estimating the coefficient variance-covariance matrix and in turn the standard errors.
oim and opg are derived from asymptotic properties of maximum likelihood estimators.
robust and cluster clustvar, are robust to some kinds of misspecification, for instance intra cluster correlation for the latter.
With analytically determined cross-stage derivatives cfbinout, applies the vcetype to the covariance estimation in the first (either robust or cluster) and the second-stage.
Yet, combining the two preliminary variance-covariance matrices to what is finally saved in e(V) does not take the vcetype into account.
In contrast, with numerically determined cross-stage derivatives (see option noanalytic), a sandwich estimator is used if the vcetype is robust or cluster.

terza(2017|2023) specifies whether the method of variance-covariance estimation is the one originally proposed by Terza (2017) or the corrected version proposed by Terza (2023).
terza(2023) is the default, which, according to Terza (2023), has a much better basis in statistical theory.
Unlike terza(2017), terza(2023) requires not only calculating first but also second (cross-stage) derivatives of the pseudo-log-likelihood function and is computationally more demanding.
Choosing the (incorrect) 2017 method may hence be a work-around if cfbinout, terza(2023) fails or takes excessive time to run, cf. option noanalytic.
The two methods often give similar estimates. However, depending on the specific application, the difference between them can still be substantial.

noanalytic requests numerical calculation of the cross-stage derivatives of the (pseudo) log-likelihood function, using the Mata function deriv().
Analytically derived cross-stage derivatives are not available for fslink(probit), nor when order(#) is specified other than the default.
For these specifications, cfbinout automatically activates noanalytic and issues a respective message.
Calculating cross-stage derivatives numerically requires the Stata do file _llcfbin_v.do to be stored in the ado-path.
For large models and big data sets, calculating the cross-derivatives numerically may require substantial computing time.
noanalytic is immaterial if terza(2017) specified, since Terza's (2017) approach to variance-covariance estimation does not involve the calculation of cross-stage derivatives.

Store/Generate

nogresenerate makes cfbinout only temporarily generate the first-stage residuals that enter the second-stage as additional regressors.
noresgenerate also prevents cfbinout from saving the estimated coefficients of these additional regressors in e(b) and reporting them in the output.
Specifying the option noresgenerate is not recommended, if the analysis aims on estimating marginal effects, e.g. using the postestimation command margins.
Two-step control function estimation rescales the estimated coefficient but still allows for estimating marginal effects consistently.
Yet, the latter requires that the auxiliary regressors are taken into account when predicting probabilities (cf. Wooldridge, 2015).

resname(stub) specifies the prefix for the names of the variables as which the first-stage residuals are saved as stub.
In other words, if varlist2 consists of the two variables endogvar1 and endogvar2, resname(stub) makes resname(stub) generate the variables stub_endogvar1 and stub_endogvar2.
If resname(stub) is not specified, cfbinout uses res as prefix.
If a higher-order control-function polynomial is requested by specifying order(#), the powers of the first-stage residuals receive the prefix-names stub2_, stub3_, etc.

replace allows cfbinout to replace existing variables that share their names with the newly generated first-stage residuals.
Specifying replace is in particularly convenient, if one estimates different specifications of a model but does not want to save the first-stage residuals from all of them.

fskeep makes cfbinout save the full first-stage regression results in e(bfs) and e(Vfs).
The first-stage coefficients are always saved in the matrix e(G), regardless of whether fskeep is specified or not.

Reporting

display_option: level(#), noci, nopvalues, noomitted, vsquish, noemptycells, baselevels, allbaselevels, nofvlabel, fvwrap(#), fvwrapon(style),
cformat(%fmt), pformat(%fmt), sformat(%fmt), and nolstretch.
They are essentially the same as for eretun display, to which they are passed through; see [R] eretun display.

Maximazation

nosearch prevents deriv() from searching for optimal values for delta, when numerically calculating cross-stage derivatives.
This reduces the run time but may also reduce the accuracy.

maximization_options for the second-stage: difficult, technique(algorithm_spec), iterate(#), tolerance(#), ltolerance(#), nrtolerance(#), qtolerance, nonrtolerance,
and from(init_specs); see [R] maximize

Example

Load Stata example data set laborsup.dta.

. webuse laborsup, clear

Use cfbinout for estimation (equivalent to using ivprobit, twostep); [R] ivprobit.

. cfbinout probit fem_work fem_educ kids (other_inc = male_educ)

Use logit link function.

. cfbinout logit fem_work fem_educ kids (other_inc = male_educ), replace

Consider having kids as binary endogenous regressor and use parents' relative education as an additional instrument.

. generate haskids = kids > 0

. generate rel_educ = male_educ/fem_educ

. cfbinout probit fem_work fem_educ (other_inc i.haskids = male_educ rel_educ), fslink(probit) replace

Recode kids as a categorical variable and use polynomial of husband's and interaction of spouses' education as instruments; use the cloglog link and second order control-function polynomial.

. recode kids (0 = 0) (1 = 1) (2 3 4 = 2), gen(kidscat)

. cfbinout cloglog fem_work fem_educ (other_inc i.kidscat = c.male_educ##c.male_educ c.fem_educ#c.male_educ), fslink(probit) order(2) replace

Saved results

cfbinout saves in e()
(in major parts passed through from logit, probit, and cloglog, respectively; descriptions partly borrowed from respective help files):

Scalars

e(N) number of observations

e(ll) pseudo log likelihood (second-stage)

e(chi2) model chi-squared

e(df_m) model degrees of freedom

e(p) model significance, p-value

e(level) confidence level

e(k_perfect) number of collinear residuals dropped from second-stage

e(chi2_exog) Wald chi-squared test of exogeneity

e(df_exog) test of exogeneity degrees of freedom

e(p_exog) test of exogeneity p-value

e(rank) rank of e(V)

e(ic) number of iterations (second-stage)

e(k) number of parameters (second-stage)

e(k_eq) number of equations in e(b) (second-stage)

e(k_dv) number of dependent variables (second-stage)

e(k_eq_model) overall number of equations

e(converged) 1 if converged, 0 otherwise (second-stage)

e(rc) return code

e(wgtsum) sum of weights

e(ll_0) pseudo log likelihood, constant-only model (second-stage)

e(order) order of control-function polynomial

e(N_clust) number of clusters (only saved with vcetype cluster)

e(N_f) number of failures (only saved with link cloglog)

e(N_s) number of successes (only saved with link cloglog)

e(N_cdf) number of completely determined failures (not saved with link cloglog)

e(N_cds) number of completely determined successes (not saved with link cloglog)

e(terza) 2023 if Terza (2023) variance estimation, 2017 otherwise

Macros

e(cmd) cfbinout

e(title) Control function link regression

e(cmdline) command as typed

e(chi2type) Wald

e(generated) variables generated by cfbinout

e(instruments) (excluded) instrumental variables

e(endog) endogenous rhs variables

e(exog) exogenous variables

e(perfect) perfectly predicted rhs variables

e(fsswitched) first-stage regressions switched to linear (only saved with fsswitch)

e(fslink) first-stage link function for binary variables

e(link) second-stage link function

e(properties) b V

e(depvar) name of depvar

e(which) max or min; whether optimizer is to perform maximization or minimization

e(vce) vcetype specified in vce()

e(vcetype) title used to label Std. Err.

e(clustvar) name of cluster variable (only saved with vcetype cluster)

e(crossderiv) analytic or numeric

e(sandwich) sandwich or nosandwich; empty if sandwich estimator was not requested

e(wtype) weight type (only saved if weights are specified)

e(wexp) = weight expression (only saved if weights are specified)

e(technique) maximization technique (second-stage)

e(ml_method) type of ml method (second-stage)

e(user) name of likelihood-evaluator program (second-stage)

e(opt) type of optimization (second-stage)

e(marginsnotok) predictions disallowed by margins margins

e(marginsok) predictions allowed by margins

e(predict) program used to implement predict

Matrices

e(b) vector of estimated coefficients

e(V) estimated coefficient variance-covariance matrix

e(G) matrix of estimated first-stage coefficients

e(bfs) vector of estimated first-stage coefficients (only saved with fskeep)

e(Vfs) estimated first-stage coefficient variance-covariance matrix (only saved with fskeep)

e(mns) vector of means of the independent variables (not saved with link cloglog)

e(rules) information about perfect predictors (second-stage, not saved with link cloglog)

e(ilog) iteration log (second-stage, up to 20 iterations)

e(gradient) gradient vector (second-stage)

Functions

e(sample) marks estimation sample

References

Liu, W. (2023). IVCLOGLOG: Stata module to estimate a complementary log-log model with endogenous covariates, instrumented via the control function approach (i.e., 2SRI),
Statistical Software Components S459239, Boston College Department of Economics, revised 18 Nov 2023.

Terza, J.V. (2023). Simpler standard errors for two-stage optimization estimators revisited, The Stata Journal 23(4), 1057-1061.

Terza, J.V. (2017). Two-stage residual inclusion estimation: A practitioners guide to Stata implementation, The Stata Journal 17(4), 916-938.

Terza, J.V. (2016). Simpler Standard Errors for Two-stage Optimization Estimators, The Stata Journal 16(2), 368–385.

Wooldridge, J.M. (2015). Control Function Methods in Applied Econometrics, The Journal of Human Resources 50(2), 420-445.

Also see

Manual: [R] cfprobit, [R] ivprobit, [R] probit, [R] logit, [R] cloglog

Help: [R] cfprobit, [R] ivprobit, [R] probit, [R] logit, [R] cloglog

Online: ivcloglog

Authors

Harald Tauchmann

Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)

Nürnberg,
Germany

E-mail: harald.tauchmann@fau.de

Elena Yurkevich

Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)

Nürnberg,
Germany

E-mail: elena.yurkevich@fau.de

Disclaimer

This software is provided "as is" without warranty of any kind, either expressed or implied. The entire risk as to the quality and
performance of the program is with you. Should the program prove defective, you assume the cost of all necessary servicing, repair or
correction. In no event will the copyright holders or their employers, or any other party who may modify and/or redistribute this software,
be liable to you for damages, including any general, special, incidental or consequential damages arising out of the use or inability to
use the program.

Acknowledgements

We gratefully acknowledge comments and suggestions by the participants of the German Stata Conference 2024 and excellent research assistance by Michail Liatos.