Skip to contents

Every estimator in this package rests on assumptions about the data, not just about the model. validity() checks those assumptions on a fitted model and reports what the data actually say, rather than leaving the question to be taken on faith. It brings together checkpoints from three sources that do not always agree with each other, so its output keeps them apart instead of collapsing them into a single yes or no verdict: the boundary conditions of Becker, Proksch and Ringle (2022), the decision tree of Yang, Qian and Xie (2025), and the standard error inflation statistic of Qian, Koschmann and Xie (2025). What gets checked depends on the estimator: for most of them it is nonnormality of the endogenous regressor, for BMW it is nonnormality of the first-stage residuals instead, and for 2sCOPE-np it is a different assumption entirely, covered at the end of this article.

A case where the assumptions hold

We reuse the simulation from “Get started with endogCopula”: an endogenous regressor built to be skewed and to share a Gaussian noise component with the error, and an exogenous regressor with nothing to do with either.

set.seed(1)
n <- 300
w <- rnorm(n)
u <- rnorm(n)
p <- rchisq(n, df = 3) + 0.3 * u
y <- 1 + 2 * p + 0.5 * w + u
dat <- data.frame(y = y, p = p, w = w)

set.seed(1)
fit_good <- CopRegPG(y ~ p | w, data = dat, nboots = 99)
validity(fit_good)
#> 
#> Validity check for PG (Park & Gupta 2012)
#> n = 300, 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    1.461       2.627 9.866 1.65 2.42e-05    TRUE     FALSE
#>     Becker et al. at n = 300: |skewness| >= 1.932, or AD > 18.964, or CvM > 3.488
#>     Yang et al.: KS p < .05
#>     Note: the two criteria disagree here. Becker et al. report a
#>     correlation of .66 between the AD statistic and the copula term's
#>     t statistic against -.03 for KS, and recommend AD or CvM; Yang et
#>     al. prefer KS because it is conservative.
#> 
#> [2] Assumption: correlation of the copula transformation term
#>     with the exogenous regressors
#>   corr(W, CTT) p (Holm)
#> w      -0.0198    0.733
#>     Joint test: R2 = 0.0003912, F = 0.1166, p = 0.733
#>     => satisfied. Park & Gupta is consistent here and more efficient.
#> 
#> [3] Error term: structural residuals xi
#>     skewness = 0.06127, excess kurtosis = 0.2633, AD = 0.3163 (p = 0.539)
#>     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.
#> 
#> [4] ICON: standard error inflation relative to uncorrected OLS
#>             SE (corrected) SE (uncorrected)   ICON
#> (Intercept)        0.24097          0.08769 2.7482
#> p                  0.08043          0.02531 3.1771
#> w                  0.06338          0.06376 0.9941
#>     => largest ICON = 3.177, below the threshold of 6.

We go through this output block by block below. The numbering in [1], [2] and so on follows the numbers validity() itself prints, which depend on the estimator and on what applies to the data at hand: an estimator with no first stage skips the step that needs one, and a step that only applies after another step fails is only printed once that earlier step has actually failed.

Nonnormality of the endogenous regressor

The endogenous regressor has to be non-normal for the copula term to carry information the regressor’s own untransformed value does not already carry, and that requirement is the identifying assumption itself. validity() reports two criteria side by side because the papers behind this package do not agree on which one to use. Becker, Proksch and Ringle (2022) recommend the Anderson-Darling or Cramer-von Mises statistics, because in their simulations those correlate much better with the actual quality of the correction than a Kolmogorov-Smirnov test does. Yang, Qian and Xie (2025) use the Kolmogorov-Smirnov p value instead, precisely because it is the more conservative of the two. A KS test flags nonnormality less readily, so passing it is a stronger signal. The thresholds Becker et al. use also depend on the sample size and on a target power for the copula term’s significance test, either 80% or 90%, set by the power argument to validity().

In the fit above, Yang ok is TRUE and Becker ok is FALSE. The KS test is confident enough to flag the regressor as non-normal, but the skewness, Anderson-Darling and Cramer-von Mises statistics do not clear Becker’s higher bar at this sample size. validity() prints a note when this happens, because it is a real disagreement in the literature and not a sign that something has gone wrong. Becker et al. report a correlation of .66 between their preferred Anderson-Darling statistic and the copula term’s t statistic, against only -.03 for Kolmogorov-Smirnov, which is why they recommend Anderson-Darling or Cramer-von Mises over KS. There is no single correct answer here. Treat agreement between the two criteria as reassuring and disagreement, as here, as a reason to also look at step 3 below (present only when Yang’s criterion fails, which it does not in this fit) and at the standard error inflation in the final block, rather than as a reason to stop at step 1 alone.

The uncorrelatedness assumption

For estimators that assume the endogenous regressor is uncorrelated with the exogenous ones, validity() tests that assumption directly. It regresses the copula term on the exogenous regressors and reports both the correlation with each one individually, Holm-adjusted for multiple testing, and a joint F test of all of them at once. In the fit above this step reports satisfied, because w was simulated to be independent of the error and, by construction, largely independent of the part of p that is correlated with the error. Two-stage estimators such as 2sCOPE and IMA do not get this step at all. They project the correlation out in their first stage, so testing for it afterward would only restate what the estimator already handles. BMW does not get it in the same form either; its diagnostics report that the correlation is not assumed to be zero rather than testing whether it is.

Exogenous regressors as identifying variation

This step only appears when step 1 has already found the endogenous regressor to be too close to normal for Yang, Qian and Xie’s criterion. It looks for a continuous exogenous regressor that is itself sufficiently non-normal (KS p < .001) and sufficiently related to the copula term in a first-stage regression (F > 10), because such a regressor could supply the identifying variation that the endogenous regressor itself falls short of. It does not appear in the fit above, because step 1’s Yang ok was already TRUE.

The structural residuals

validity() always reports the skewness, excess kurtosis, Anderson-Darling statistic and its p value for the structural residuals, xi = y - mu - P alpha - W beta. It is tempting to read a normal looking residual as confirmation that the model is fine, but the papers behind this package disagree about what the error is even allowed to look like, and the residual on its own cannot settle that disagreement. Becker, Proksch and Ringle (2022) find that a nonnormal error breaks consistency in models with an intercept. Yang, Qian and Xie (2025) and Qian, Koschmann and Xie (2025) allow a nonnormal error under a decomposition of xi into a normally distributed part that carries the entire dependence with the regressors and an independent, possibly nonnormal remainder. The residuals show the whole of xi, not that normal part on its own, so their shape neither confirms nor rules out either position. Whether the decomposition plausibly holds has to be argued from what you believe is causing the endogeneity in the first place, not read off this one diagnostic.

ICON: the standard error inflation

The last block compares the corrected standard error to the uncorrected OLS standard error, from the same bootstrap resamples, for every coefficient in the model. The ratio is called ICON, and Qian, Koschmann and Xie (2025) flag a value above 6 as a sign of weak identification or a poorly specified dependence structure. The correction is not wrong exactly, but it is buying its protection against endogeneity at a cost in precision large enough to be a warning sign on its own. In the fit above the largest ICON is well under 6, which along with the satisfied uncorrelatedness assumption is why we call this a case where the assumptions hold.

A case where the assumptions are violated

Now the other side. sim_endog, the dataset shipped with the package, has an endogenous regressor that is noticeably correlated with one of its exogenous regressors, which is exactly the situation CopRegPG() is not built for.

data(sim_endog)
set.seed(1)
idx <- sample(nrow(sim_endog), 300)
d <- sim_endog[idx, ]
cor(d$z_endog, d$w_instr)
#> [1] 0.5630987

set.seed(1)
fit_bad <- CopRegPG(y ~ z_endog | x_exog + w_instr, data = d, nboots = 99)
validity(fit_bad)
#> 
#> Validity check for PG (Park & Gupta 2012)
#> n = 300, 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
#> z_endog    0.036       0.136 0.442 0.04 0.77   FALSE     FALSE
#>     Becker et al. at n = 300: |skewness| >= 1.932, 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)
#> x_exog       -0.0399    0.491
#> w_instr       0.5620   <1e-16
#>     Joint test: R2 = 0.3197, F =  69.8, p = < 2.2e-16
#>     => violated. Park & Gupta is inconsistent here (Haschka, 2025).
#> 
#> [3] Exogenous regressors as identifying variation
#>     (continuous, KS p < .001, first-stage F > 10)
#>     Not available: this estimator has no first stage.
#> 
#> [4] Error term: structural residuals xi
#>     skewness = -0.01074, excess kurtosis = 0.04212, AD = 0.2891 (p = 0.613)
#>     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.15593          0.06276  2.4848
#> z_endog            0.67571          0.06266 10.7838
#> x_exog             0.05709          0.05727  0.9968
#> w_instr            0.05970          0.05868  1.0174
#>     => largest ICON = 10.78, above the threshold of 6: weak
#>        identification or a misspecified dependence model.

Step 1 shows z_endog as close enough to normal that both Yang ok and Becker ok come back FALSE, so the endogenous regressor itself is already a weaker source of identification here than in the earlier example. Step 2 reports violated. The copula term correlates with w_instr at about 0.56, with a Holm adjusted p value far below any reasonable significance level, which is precisely the correlation with w_instr we found directly on the raw data above. validity() is not telling us anything we could not have checked by hand; it is telling us what that correlation does to the assumption PG needs. The consequence shows up in the last block. The largest ICON is well above the threshold of 6, meaning the corrected standard error on z_endog is many times the uncorrected OLS one. Put together, this fit fails every check that is relevant to PG specifically. The “Choosing an estimator” article shows what 2sCOPE, IMA, BMW and JAMS do with the same data, because each of them relaxes the assumption that fails here.

BMW: the same steps, applied to the first-stage residuals

BMW’s identification requirement falls on the residuals of its first stage rather than on the endogenous regressor directly, so validity() tests those residuals instead when it is looking at a BMW fit, and the step 1 heading says so explicitly:

set.seed(1)
fit_bmw <- CopRegBMW(y ~ z_endog | x_exog + w_instr, data = d, nboots = 99)
validity(fit_bmw)
#> 
#> Validity check for BMW (Breitung, Mayer & Wied 2024)
#> n = 300, intercept: yes, target power 80%
#> Sources: Becker, Proksch & Ringle (2022); Yang, Qian & Xie (2025);
#>          Qian, Koschmann & Xie (2025)
#> 
#> [1] Nonnormality of the first-stage residuals
#>     Theorem 2.1 of Breitung, Mayer & Wied (2024) identifies the model if and only
#>     if the first-stage error is not normal, so that is what is tested here.
#>         skewness ex.kurtosis    AD   CvM  KS p Yang ok Becker ok
#> z_endog   -0.009       0.047 0.175 0.022 0.976   FALSE     FALSE
#>     Becker et al. at n = 300: |skewness| >= 1.932, or AD > 18.964, or CvM > 3.488
#>     Yang et al.: KS p < .05
#> 
#> [2] Exogenous regressors as identifying variation
#>     (continuous, KS p < .001, first-stage F > 10)
#>         continuous  KS p F: z_endog qualifies
#> x_exog        TRUE 0.360      0.001     FALSE
#> w_instr       TRUE 0.907      0.005     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.
#> 
#> [3] Error term: structural residuals xi
#>     skewness = -0.01793, excess kurtosis = -0.3475, AD = 0.2755 (p = 0.657)
#>     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.
#> 
#> [4] ICON: standard error inflation relative to uncorrected OLS
#>             SE (corrected) SE (uncorrected)   ICON
#> (Intercept)        0.10908          0.06276  1.738
#> z_endog            1.00395          0.06266 16.022
#> x_exog             0.09951          0.05727  1.737
#> w_instr            0.66789          0.05868 11.383
#>     => largest ICON = 16.02, above the threshold of 6: weak
#>        identification or a misspecified dependence model.

Everything else about reading the output is the same as above: the nonnormality criteria, the structural residual diagnostics, and the ICON threshold all mean what they meant before. The step testing correlation with the exogenous regressors as an assumption does not appear for BMW, because BMW does not assume that correlation away in the first place.

2sCOPE-np: a different assumption altogether

CopReg2sCOPEnp() does not rely on nonnormality of the endogenous regressor at all, because its copula term comes from a nonparametrically estimated conditional distribution rather than from a marginal one. validity() on a 2sCOPE-np fit checks Assumption 3 of Hu, Qian and Xie (2025) instead, the requirement that the copula term is not simply a linear combination of the intercept, the endogenous regressor and the exogenous regressors. It is reported as omega, one minus the R-squared of a regression of the copula term on everything else in the model. A value of omega near zero means the augmented regression is close to singular, which is the practical way this assumption fails. The paper’s own recommendation is to read the standard error inflation in the ICON block as the operational test of this assumption, because it is exactly that kind of collinearity that inflates the standard errors. This package’s 2sCOPE-np examples live in “Choosing an estimator” and are not run there either, because cross-validated bandwidth selection makes the estimator slow; the shape of its validity() output, though, is the one just described rather than the nonnormality table used everywhere else in this article.

Reading validity() as a whole

No single number from validity() is a verdict on its own; that is why the output keeps five separate checks apart rather than folding them into one. A fit that fails the nonnormality criteria can still be fine if an exogenous regressor supplies enough identifying variation on its own. A fit that passes every check can still have an ICON high enough to make the resulting standard errors impractical. Read the checks together: nonnormality of the source the estimator actually depends on, whether the uncorrelatedness assumption holds where it applies, what the structural residuals do and do not settle, and finally whether the price paid in standard error inflation is one you are willing to pay.