
Copula endogeneity correction of Hu, Qian and Xie (2025) (2sCOPE-np)
Source:R/copreg-2scope-np.R
CopReg2sCOPEnp.RdInstrument-free correction for an endogenous regressor that
replaces the first-stage regression used by every other estimator in this
package with a nonparametric estimate of the conditional distribution of
the endogenous regressor \(P\) given the exogenous regressors \(W\),
\(C = \Phi^{-1}(\hat F(P \mid W))\), using the kernel conditional CDF
estimator of Li and Racine (2008) as implemented in np::npcdist().
Unlike every other estimator here, 2sCOPE-np has no cdf and no
ties argument: there is no marginal CDF to choose, and supplying
either through ... is an error rather than being silently ignored. It
is also the only estimator in the package that tolerates discrete
endogenous regressors (counts, binary treatments), because the
conditional CDF smooths the regressor itself rather than requiring a
continuous marginal transform. Finally, it is slow: bandwidths are
chosen by cross-validation, an O(n^2) computation, and by default that
selection is repeated from scratch in every bootstrap replicate.
Usage
CopReg2sCOPEnp(
formula,
data,
condition = NULL,
groups = NULL,
heterogeneous = NULL,
demean = NULL,
bwmethod = c("cv.ls", "normal-reference"),
bw.refit = TRUE,
nboots = 199,
subset = NULL,
contrasts = NULL,
parallel = FALSE,
ncores = NULL,
verbose = interactive(),
...
)Arguments
- formula
A two-part formula,
y ~ endogenous | exogenous, as used throughout this package (seeCopRegPG()). Endogenous regressors must be numeric but, uniquely for this estimator, may be discrete. Without an exogenous part the call is redirected toCopRegPG().- data
A
data.framecontaining all variables named informula.- condition
Character vector naming which exogenous variables the conditional CDF conditions on.
NULL(the default) uses all exogenous variables except polynomial and interaction terms, which the kernel estimator already accommodates without being told about them explicitly.- groups
Character vector. Instead of smoothing these variables with their own kernel, estimate the conditional CDF separately within each of their joint categories, still producing one copula coefficient per endogenous regressor.
NULL(the default) smooths them like any other conditioning variable.- heterogeneous
Character vector naming variables whose joint categories may carry a different copula structure, i.e. different endogeneity (Proposition 1 of Hu, Qian & Xie 2025). The conditional CDF is then estimated separately within each category and the copula terms are parameterised against the first category as the reference group, so that the remaining coefficients test whether the endogeneity differs across groups.
NULL(the default) imposes one common structure.- demean
Character vector naming variables to treat as fixed effects: their categories are removed by within-group demeaning of the endogenous regressor(s) and of the continuous conditioning variables before Stage 1, instead of being smoothed or split into cells.
NULL(the default) performs no demeaning.- bwmethod
Bandwidth selection method passed to
np::npcdistbw():"cv.ls"(the default), the least-squares cross-validation of Li, Lin & Racine (2013) used by the paper, or"normal-reference", a cheaper, non-cross-validated alternative.- bw.refit
Logical.
TRUE(the default) re-selects the bandwidths, cross-validation included, in every bootstrap replicate, which is the paper's own procedure and is what makes the bootstrap standard errors account for first-stage variability – and is why this estimator is slow.FALSEreuses the full-sample bandwidths throughout the bootstrap and re-estimates only the conditional CDF, which is faster but a deviation from the paper.- nboots
Number of bootstrap replicates used for the standard errors.
- subset
Optional logical vector selecting a subset of observations, as in
lm().- contrasts
Optional list of contrasts, passed to
model.matrix().- parallel
FALSE,TRUE,"multicore"or"snow": whether and how to parallelize the bootstrap.- ncores
Number of worker processes when
parallelis notFALSE;NULLuses one fewer than the number of cores detected.- verbose
Logical. Report progress and, before the bootstrap begins, the estimated total run time (Stage 1 is timed once and the elapsed time multiplied by
nboots).- ...
Further arguments passed on to
np::npcdistbw(), e.g.ckertype,ukertype,okertype,nmulti. Passingcdfortieshere raises an error: this estimator has neither argument.
Value
An object of class "copreg", a list including:
coefficients,std.error,vcovaugmented-regression coefficient estimates and their bootstrap standard errors/covariance
rho,rho.sethe sample correlation of the structural residual with each copula term, and its bootstrap standard error
fitted.values,residualsfrom the structural model, with the copula terms excluded
copula.terms,copula.datathe generated copula regressors and the underlying \(\Phi^{-1}(\hat F(P \mid W))\) values
copula.groupswhen
heterogeneousis used, a data frame identifying which copula column belongs to which cellbandwidthsthe cross-validated Stage 1 bandwidths from the full sample, one row per conditioning variable (and per cell/ regressor when
groupsor several endogenous regressors are used)boot,ols.coefficients,ols.std.error,iconthe bootstrap draws, the uncorrected OLS benchmark from the same resamples, and the resulting standard-error inflation
diagnosticsthe identification checks reported by
validity()
See CopRegPG() for the methods common to every estimator in this
package (coef(), vcov(), summary(), predict(), ...).
Details
Without exogenous regressors the conditional CDF collapses to the
marginal one and the estimator reduces to Park & Gupta; the call is then
redirected to CopRegPG() with a warning. Otherwise the exogenous side
can be handled three ways, combinable: smoothed by the kernel itself
(the default), cut into cells with groups/heterogeneous, or swept out
by within-group demeaning with demean. heterogeneous additionally
lets the copula structure differ across the named cells (Proposition 1
of Hu, Qian & Xie 2025), parameterised against the first cell as the
reference group.
References
Hu, X., Y. Qian, and H. Xie (2025). Correcting endogeneity via nonparametric copula control functions. National Bureau of Economic Research Working Paper 33607. doi:10.3386/w33607
Li, Q. and J. S. Racine (2008). Nonparametric estimation of conditional CDF and quantile functions with mixed categorical and continuous data. Journal of Business & Economic Statistics 26(4), 423-434.
Li, Q., J. Lin, and J. S. Racine (2013). Optimal bandwidth selection for nonparametric conditional distribution and quantile functions. Journal of Business & Economic Statistics 31(1), 57-65.
Hayfield, T. and J. S. Racine (2008). Nonparametric econometrics: The np package. Journal of Statistical Software 27(5), 1-32.
Examples
# \donttest{
data(sim_endog)
set.seed(1)
small <- sim_endog[sample(nrow(sim_endog), 80), ]
if (requireNamespace("np", quietly = TRUE)) {
fit <- CopReg2sCOPEnp(y ~ z_endog | x_exog, data = small, nboots = 25)
summary(fit)
}
#>
#> Copula endogeneity correction: 2sCOPE-np (Hu, Qian & Xie 2025)
#>
#> Call:
#> CopReg2sCOPEnp(formula = y ~ z_endog | x_exog, data = small,
#> nboots = 25)
#>
#> Residuals of the augmented regression (u = xi - C gamma):
#> Min 1Q Median 3Q Max
#> -2.49556 -0.77935 0.04487 0.78475 2.40727
#>
#> Residuals of the structural model (xi = y - mu - P alpha - W beta):
#> Min 1Q Median 3Q Max
#> -8.6144 -2.1109 -0.1758 2.1805 9.1436
#>
#> Coefficients:
#> Estimate Std. Error z value Pr(>|z|)
#> (Intercept) 1.5167 0.1988 7.629 2.37e-14 ***
#> z_endog -1.1328 0.5271 -2.149 0.0316 *
#> x_exog 1.5427 0.1543 9.995 < 2e-16 ***
#> z_endog_cop 3.4832 0.6632 5.252 1.50e-07 ***
#> ---
#> Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#>
#> Endogeneity is read off the copula terms above. The control function is
#> E(o | p, w) = sigma_o * rho * C_p, so only the product sigma_o * rho
#> enters the regression and rho is not separately identified; a copula
#> coefficient of zero means no endogeneity.
#>
#> Fit, on 76 residual degrees of freedom:
#> augmented structural
#> Residual standard error 1.1241 3.5374
#> R-squared 0.8558 -0.4280
#> Adjusted R-squared 0.8501 -0.4844
#> Standard errors from 25 bootstrap replicates.
#> Bandwidths of the conditional CDF estimation:
#> regressor cell variable bandwidth
#> 1 z_endog z_endog 0.3515
#> 2 z_endog x_exog 247.7126
#> Pr(>|z|): Wald test using the normal approximation,
#> z = Estimate / Std. Error, with the bootstrap standard error.
#> See confint(object, type = "percentile") for bootstrap percentile intervals.
#>
#> --- Identification diagnostics ------------------------------------
#>
#> Correlation of the copula terms with the exogenous regressors
#> (the conditional CDF conditions on them, so a well estimated one leaves
#> these correlations near zero; large values point at a poorly estimated
#> conditional CDF rather than at a violated assumption):
#> max |corr| with p (Holm) joint R2 joint p
#> z_endog 0.03015 x_exog 0.7913 0.0009088 0.7907
#> full matrix in summary(object)$diagnostics$exog.correlation.matrix
#>
#> Collinearity of the copula terms (omega near 0 = weakly identified):
#> corr(P, C) omega
#> z_endog_cop 0.9986 0.002878
#>
# }