Brings together the checkpoints of three sources, kept apart rather than
merged into one verdict: the boundary conditions of Becker, Proksch &
Ringle (2022, Figure 8) for the Park & Gupta method, the decision tree of
Yang, Qian & Xie (2025, Figure 2), and the ICON standard-error inflation
statistic of Qian, Koschmann & Xie (2025, Table 4). What is checked depends
on the estimator's own identification condition
(object$id.condition): for most estimators it is non-normality of
the endogenous regressors; for BMW it falls on the first-stage residuals;
for 2sCOPE-np it is Assumption 3 of Hu, Qian & Xie (2025) rather than
non-normality of P.
Usage
# S3 method for class 'copreg'
validity(object, level = 0.05, power = 0.8, ...)Value
An object of class "copreg.validity", a list whose main
elements are step1 (non-normality table), step2 (the
uncorrelatedness assumption, where relevant), step3 (exogenous
regressors as identifying variation, where relevant), step4
(error-term diagnostics), and icon (the standard-error inflation
table). Has a print.copreg.validity method.
References
Becker, J.-M., D. Proksch, and C. M. Ringle (2022). Revisiting Gaussian copulas to handle endogenous regressors. Journal of the Academy of Marketing Science 50, 46-66.
Yang, F., Y. Qian, and H. Xie (2025). Addressing endogeneity using a two-stage copula generated regressor approach. Journal of Marketing Research 62(4), 601-623.
Qian, Y., A. Koschmann, and H. Xie (2025). A practical guide to endogeneity correction using copulas. Journal of Marketing.
Breitung, J., A. Mayer, and D. Wied (2024). Asymptotic properties of endogeneity corrections using nonlinear transformations. The Econometrics Journal 27(3), 362-383.
Hu, X., Y. Qian, and H. Xie (2025). Correcting endogeneity via nonparametric copula control functions. NBER Working Paper 33607.
Examples
set.seed(1)
n <- 150
w <- rnorm(n)
p <- 0.4 * w + rt(n, df = 3)
xi <- 0.5 * p + rnorm(n)
y <- 1 + 2 * p + 1.5 * w + xi
dat <- data.frame(y = y, p = p, w = w)
fit <- endogCopula:::.copreg_fit(
formula = y ~ p | w, data = dat,
ctor = endogCopula:::.ctor_twostage(TRUE),
method = "2sCOPE", cdf = "rank.n", ties = "max",
nboots = 25, verbose = FALSE)
validity(fit, level = 0.05, power = 0.8)
#>
#> Validity check for 2sCOPE
#> n = 150, intercept: yes, target power 80%
#> Sources: Becker, Proksch & Ringle (2022); Yang, Qian & Xie (2025);
#> Qian, Koschmann & Xie (2025)
#>
#> [1] Nonnormality of the endogenous regressors
#> skewness ex.kurtosis AD CvM KS p Yang ok Becker ok
#> p 0.962 5.978 1.604 0.261 0.343 FALSE FALSE
#> Becker et al. at n = 150: |skewness| >= not attainable, or AD > 18.964, or CvM > 3.488
#> Yang et al.: KS p < .05
#>
#> [2] Assumption: correlation of the copula transformation term
#> with the exogenous regressors
#> corr(W, CTT) p (Holm)
#> w -0.1761 0.0309
#> Joint test: R2 = 0.03102, F = 4.737, p = 0.0311
#> => violated. Park & Gupta is inconsistent here (Haschka, 2025).
#>
#> [3] Exogenous regressors as identifying variation
#> (continuous, KS p < .001, first-stage F > 10)
#> continuous KS p F: p qualifies
#> w TRUE 0.847 4.797 FALSE
#> => none qualifies. The conditions are conservative and not
#> necessary; Yang et al. (2025) propose a bootstrap procedure to gauge
#> the finite-sample bias in this situation.
#>
#> [4] Error term: structural residuals xi
#> skewness = -0.02121, excess kurtosis = -0.3975, AD = 0.2139 (p = 0.849)
#> Becker et al. (2022) find that with a nonnormal error the approach
#> is no longer consistent in models with an intercept. Yang et al.
#> (2025) and Qian et al. (2025) do permit a nonnormal error, but only
#> under the decomposition xi = U + V into a normally distributed
#> endogenous part U, which carries the entire dependence with the
#> regressors, and an independent nonnormal V. The residuals show xi,
#> not U, so their skewness neither establishes nor rules out a
#> violation; whether that decomposition holds has to be argued from
#> the suspected sources of endogeneity.
#>
#> [5] ICON: standard error inflation relative to uncorrected OLS
#> SE (corrected) SE (uncorrected) ICON
#> (Intercept) 0.09116 0.08483 1.075
#> p 0.22755 0.05394 4.219
#> w 0.11580 0.08547 1.355
#> => largest ICON = 4.219, below the threshold of 6.
#>
