Introduction
ivreg2r provides comprehensive instrumental variables
and GMM estimation with automatic diagnostic tests. It supports 2SLS,
LIML, Fuller, k-class, two-step efficient GMM, and continuously-updated
(CUE) estimators with classical, robust, cluster-robust, HAC, and
Driscoll-Kraay standard errors. It is an R implementation inspired by
Stata’s ivreg2 (Baum, Schaffer & Stillman), designed
for applied researchers — especially those migrating from Stata who
expect rich diagnostics reported alongside their IV estimates.
This vignette covers the core workflow: OLS, 2SLS, diagnostics,
robust and cluster-robust inference, weights, and broom integration. For
LIML, Fuller, and k-class estimation, weak-instrument-robust inference,
and model-comparison workflows, see
vignette("advanced-iv"). For HAC/AC standard errors, GMM,
CUE, partialling, and panel VCE options, see
vignette("time-series-gmm").
We’ll use the Card (1995) dataset throughout this vignette. Card uses geographic proximity to a four-year college as an instrument for years of education in a log-wage equation, exploiting the idea that growing up near a college reduces the cost of attending and therefore shifts educational attainment. The exclusion restriction — that proximity affects wages only through schooling — is an identifying assumption, not something the data can fully verify: proximity could in principle be correlated with unobserved determinants of wages, a concern Card (1995) discusses at length.
OLS baseline
Give ivreg2() an ordinary regression formula with no
| separators — the same y ~ x1 + x2 you would
pass to lm() — and it fits by ordinary least squares. In
Stata this is the OLS special case of the same command:
ivreg2 lwage educ exper ... with no
(educ = ...) block. We use the control set from Card (1995,
Table 2), which is also the specification in Example 15.4 of Wooldridge
(2020): years of schooling, experience and its square, race, urban
residence (smsa), current region (south), and
the 1966 residence indicators (smsa66 together with the
census-region dummies). The Card data ship the census-region indicators
already expanded as separate dummies,
reg661–reg669 with reg661 the
omitted base, so we list reg662–reg669
directly:
fit_ols <- ivreg2(
lwage ~ educ + exper + expersq + black + smsa + south + smsa66 +
reg662 + reg663 + reg664 + reg665 + reg666 + reg667 + reg668 + reg669,
data = card
)
summary(fit_ols)
#>
#> OLS Estimation
#>
#> Call:
#> ivreg2(formula = lwage ~ educ + exper + expersq + black + smsa +
#> south + smsa66 + reg662 + reg663 + reg664 + reg665 + reg666 +
#> reg667 + reg668 + reg669, data = card)
#>
#> Observations: 3,010
#> VCV type: Classical (iid)
#>
#> Coefficients:
#> Estimate Std. Error z value Pr(>|z|)
#> (Intercept) 4.6208069 0.0740352 62.414 < 2e-16 ***
#> educ 0.0746932 0.0034890 21.408 < 2e-16 ***
#> exper 0.0848320 0.0066066 12.841 < 2e-16 ***
#> expersq -0.0022870 0.0003158 -7.242 4.41e-13 ***
#> black -0.1990123 0.0181997 -10.935 < 2e-16 ***
#> smsa 0.1363846 0.0200470 6.803 1.02e-11 ***
#> south -0.1479550 0.0259107 -5.710 1.13e-08 ***
#> smsa66 0.0262417 0.0193959 1.353 0.17607
#> reg662 0.0963671 0.0358024 2.692 0.00711 **
#> reg663 0.1445400 0.0350309 4.126 3.69e-05 ***
#> reg664 0.0550755 0.0415465 1.326 0.18496
#> reg665 0.1280248 0.0417281 3.068 0.00215 **
#> reg666 0.1405174 0.0451265 3.114 0.00185 **
#> reg667 0.1179810 0.0446832 2.640 0.00828 **
#> reg668 -0.0564361 0.0511215 -1.104 0.26961
#> reg669 0.1185697 0.0387267 3.062 0.00220 **
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> ---
#> R-squared: 0.2998
#> Adj. R-squared: 0.2963
#> Wald chi2(15): 85.5 (p < 2.2e-16)
#> Root MSE: 0.3713The point estimates are identical to lm(), and the model
uses the same estimation infrastructure as the IV models below, so
switching between OLS and 2SLS requires only a formula change. The
default reporting follows Stata’s conventions, however: z
statistics rather than t statistics, standard errors without the
finite-sample N - K correction, and Root MSE computed as sqrt(RSS/N).
Setting small = TRUE reproduces lm()’s
standard errors, t statistics, and sigma exactly. (For weighted
models, coefficients and small = TRUE standard errors still
match lm(), but sigma is defined differently — see Weighted
estimation below.)
Two-stage least squares
To estimate by two-stage least squares, mark the endogenous regressor
and its instruments with the | separator. Where Stata
writes ivreg2 lwage <controls> (educ = nearc4),
ivreg2r writes
lwage ~ <controls> | educ | nearc4: the exogenous
regressors first, then the endogenous regressor after the first
|, then the excluded instruments after the second. Each
variable is listed once, and the exogenous regressors are used as
instruments automatically.
Here we instrument educ with nearc4 (grew
up near a four-year college). The robust, first-stage, and weighted fits
below all reuse this same specification, so we write the formula out
once and store it:
iv_formula <- lwage ~ exper + expersq + black + smsa + south + smsa66 +
reg662 + reg663 + reg664 + reg665 + reg666 + reg667 + reg668 + reg669 |
educ | nearc4
fit_iv <- ivreg2(iv_formula, data = card)
summary(fit_iv)
#>
#> 2SLS Estimation
#>
#> Call:
#> ivreg2(formula = iv_formula, data = card)
#>
#> Observations: 3,010
#> VCV type: Classical (iid)
#>
#> Coefficients:
#> Estimate Std. Error z value Pr(>|z|)
#> (Intercept) 3.6661519 0.9223682 3.975 7.05e-05 ***
#> educ 0.1315038 0.0548174 2.399 0.016442 *
#> exper 0.1082711 0.0235956 4.589 4.46e-06 ***
#> expersq -0.0023349 0.0003326 -7.020 2.22e-12 ***
#> black -0.1467758 0.0537564 -2.730 0.006326 **
#> smsa 0.1118084 0.0315777 3.541 0.000399 ***
#> south -0.1446715 0.0272120 -5.316 1.06e-07 ***
#> smsa66 0.0185311 0.0215511 0.860 0.389862
#> reg662 0.1007677 0.0375854 2.681 0.007340 **
#> reg663 0.1482588 0.0367162 4.038 5.39e-05 ***
#> reg664 0.0498971 0.0436234 1.144 0.252701
#> reg665 0.1462719 0.0469387 3.116 0.001832 **
#> reg666 0.1629029 0.0517714 3.147 0.001652 **
#> reg667 0.1345722 0.0492708 2.731 0.006309 **
#> reg668 -0.0830770 0.0591734 -1.404 0.160332
#> reg669 0.1078142 0.0417024 2.585 0.009729 **
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> ---
#> R-squared: 0.2382
#> Adj. R-squared: 0.2343
#> Wald chi2(15): 51.0 (p < 2.2e-16)
#> Root MSE: 0.3873
#>
#> Underidentification test (Anderson canon. corr. LM statistic):
#> Chi-sq(1) = 13.27 (p = 0.0003)
#>
#> Weak identification test:
#> Cragg-Donald Wald F: 13.26
#> Stock-Yogo critical values (IV size):
#> 10% maximal IV size 16.38
#> 15% maximal IV size 8.96
#> 20% maximal IV size 6.66
#> 25% maximal IV size 5.53
#>
#> Overidentification test (Sargan): (equation exactly identified)
#>
#> Weak-instrument-robust inference:
#> H0: B1=0 and orthogonality conditions are valid
#> Anderson-Rubin Wald F(1,2994) = 5.42 (p = 0.0200)
#> Anderson-Rubin Wald Chi-sq(1) = 5.44 (p = 0.0196)
#> Stock-Wright LM S Chi-sq(1) = 5.43 (p = 0.0197)
#>
#> Endogeneity test:
#> Chi-sq(1) = 1.17 (p = 0.2786)
#> Tested: educ
#>
#> First-stage diagnostics:
#> Endogenous F-stat p-value Partial R2 Shea PR2 SW F AP F
#> educ 13.26 0.0003 0.0044 0.0044 13.26 13.26
#>
#> Instrumented: educ
#> Included instruments: exper, expersq, black, smsa, south, smsa66, reg662, reg663, reg664, reg665, reg666, reg667, reg668, reg669
#> Excluded instruments: nearc4All 3,010 observations are used, and the IV estimate of the return to schooling (0.1315, versus 0.0747 by OLS) replicates the published estimates for this specification (Card, 1995, Table 2; Wooldridge, 2020, Example 15.4).
The formula has three groups, separated by the two |
bars, mapping onto the pieces of the Stata command:
| Group | Contents | In ivreg2 lwage ... (educ = nearc4)
|
|---|---|---|
Before the first |
|
Dependent variable, then exogenous regressors |
lwage, then the controls |
Between the two |
|
Endogenous regressor(s) | educ |
After the second |
|
Excluded instruments | nearc4 |
The full instrument set is the union of the exogenous regressors and the excluded instruments; you never list the exogenous regressors twice.
Understanding the diagnostics
The summary() output reports several diagnostic tests
automatically. This section walks through each one, using the values
from the fit above.
Weak identification
The fit above reports a Cragg-Donald Wald F of 13.26. This statistic tests whether the excluded instruments are weak — that is, only weakly correlated with the endogenous regressors. Weak instruments lead to biased 2SLS estimates and unreliable standard errors.
Stock-Yogo critical values provide formal thresholds for the F statistic. Two types exist:
- IV size: the critical value such that the maximal rejection rate of a nominal 5% Wald test on the endogenous regressors’ coefficients is no more than 10%, 15%, 20%, or 25%. “Maximal” means the worst case over all possible true parameter values. For one endogenous variable and one instrument, the 10% maximal-size critical value is 16.38.
- IV relative bias: the critical value such that the maximum relative bias of 2SLS (relative to OLS bias) is no more than 5%, 10%, 20%, or 30%. Stock and Yogo tabulate these only when the number of overidentifying restrictions is at least two: the measure relies on the finite-sample moments of the 2SLS estimator, which exist only up to the degree of overidentification (Stock & Yogo, 2005; Baum, Schaffer & Stillman, 2007, p. 490). That is why neither this just-identified fit nor the overidentified fit below displays them: both have fewer than two overidentifying restrictions.
Here the Cragg-Donald F of 13.26 falls short of the 10% maximal-size
critical value of 16.38 but clears the 15% value of 8.96 — a genuinely
borderline case. A 5% Wald test on educ could reject as
often as 15% of the time under the null, so the conventional t-statistic
should be read with some suspicion. This is exactly the situation the
weak-instrument-robust Anderson-Rubin test (below) is designed for.
One caution: the Stock-Yogo critical values are tabulated for the
Cragg-Donald statistic under i.i.d. errors. Under a robust, cluster, or
HAC VCE the reported statistic is instead the Kleibergen-Paap rk Wald F,
and Baum, Schaffer & Stillman (2007, p. 490) recommend applying the
i.i.d. values to it only with caution, or falling back on the Staiger
& Stock (1997) rule that F should exceed 10. See
?ivreg2 and vignette("advanced-iv") for the
fuller discussion.
Underidentification
The fit above reports an Anderson LM statistic of 13.27 (p = 0.00027). The underidentification test asks whether the excluded instruments have any correlation with the endogenous regressors. Formally, the null hypothesis is that the matrix of reduced-form coefficients on the excluded instruments has rank K1 - 1, where K1 is the number of endogenous regressors — i.e., that the equation is underidentified. With a single endogenous regressor, as here, this reduces to the intuitive statement that the instruments are irrelevant. Rejection is good news: it means the model is identified.
With several endogenous regressors the test covers the whole system, failing to reject if any one of them is unidentified, so the per-regressor first-stage statistics below are the finer diagnostic. Under i.i.d. errors this is the Anderson (1951) canonical-correlations LM test; under heteroskedasticity or clustering it becomes the Kleibergen-Paap (2006) rk LM statistic.
Underidentification is distinct from weak identification. The underidentification test asks “is there any correlation at all?” while the weak identification test asks “is there enough correlation for reliable inference?” Here the underidentification test rejects decisively even though the instrument is borderline-weak by the Stock-Yogo standard — a common pattern, and a reminder that rejecting underidentification is not by itself evidence of strong instruments.
Overidentification
When there are more excluded instruments than endogenous regressors,
the model is overidentified and we can test whether the instruments are
valid (i.e., uncorrelated with the structural error). Adding proximity
to a two-year college (nearc2) as a second
instrument gives the specification of Computer Exercise C5, Chapter 15,
in Wooldridge (2020):
fit_overid <- ivreg2(
lwage ~ exper + expersq + black + smsa + south + smsa66 +
reg662 + reg663 + reg664 + reg665 + reg666 + reg667 + reg668 + reg669 |
educ | nearc2 + nearc4,
data = card
)
summary(fit_overid)
#>
#> 2SLS Estimation
#>
#> Call:
#> ivreg2(formula = lwage ~ exper + expersq + black + smsa + south +
#> smsa66 + reg662 + reg663 + reg664 + reg665 + reg666 + reg667 +
#> reg668 + reg669 | educ | nearc2 + nearc4, data = card)
#>
#> Observations: 3,010
#> VCV type: Classical (iid)
#>
#> Coefficients:
#> Estimate Std. Error z value Pr(>|z|)
#> (Intercept) 3.2367114 0.8825567 3.667 0.000245 ***
#> educ 0.1570593 0.0524383 2.995 0.002743 **
#> exper 0.1188149 0.0227454 5.224 1.75e-07 ***
#> expersq -0.0023565 0.0003466 -6.799 1.05e-11 ***
#> black -0.1232778 0.0520112 -2.370 0.017778 *
#> smsa 0.1007530 0.0314355 3.205 0.001350 **
#> south -0.1431945 0.0283691 -5.048 4.48e-07 ***
#> smsa66 0.0150626 0.0222765 0.676 0.498937
#> reg662 0.1027473 0.0391861 2.622 0.008741 **
#> reg663 0.1499316 0.0382896 3.916 9.01e-05 ***
#> reg664 0.0475676 0.0454799 1.046 0.295605
#> reg665 0.1544801 0.0484336 3.190 0.001425 **
#> reg666 0.1729728 0.0532743 3.247 0.001167 **
#> reg667 0.1420355 0.0509858 2.786 0.005340 **
#> reg668 -0.0950611 0.0608178 -1.563 0.118041
#> reg669 0.1029760 0.0433068 2.378 0.017415 *
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> ---
#> R-squared: 0.1702
#> Adj. R-squared: 0.1660
#> Wald chi2(15): 47.1 (p < 2.2e-16)
#> Root MSE: 0.4042
#>
#> Underidentification test (Anderson canon. corr. LM statistic):
#> Chi-sq(2) = 15.79 (p = 0.0004)
#>
#> Weak identification test:
#> Cragg-Donald Wald F: 7.89
#> Stock-Yogo critical values (IV size):
#> 10% maximal IV size 19.93
#> 15% maximal IV size 11.59
#> 20% maximal IV size 8.75
#> 25% maximal IV size 7.25
#>
#> Overidentification test (Sargan):
#> Chi-sq(1) = 1.25 (p = 0.2639)
#>
#> Weak-instrument-robust inference:
#> H0: B1=0 and orthogonality conditions are valid
#> Anderson-Rubin Wald F(2,2993) = 5.24 (p = 0.0053)
#> Anderson-Rubin Wald Chi-sq(2) = 10.55 (p = 0.0051)
#> Stock-Wright LM S Chi-sq(2) = 10.51 (p = 0.0052)
#>
#> Endogeneity test:
#> Chi-sq(1) = 2.94 (p = 0.0864)
#> Tested: educ
#>
#> First-stage diagnostics:
#> Endogenous F-stat p-value Partial R2 Shea PR2 SW F AP F
#> educ 7.89 0.0004 0.0052 0.0052 7.89 7.89
#>
#> Instrumented: educ
#> Included instruments: exper, expersq, black, smsa, south, smsa66, reg662, reg663, reg664, reg665, reg666, reg667, reg668, reg669
#> Excluded instruments: nearc2, nearc4The Sargan (1958) test (for iid models) or Hansen (1982) J test (for robust/cluster models) tests the null hypothesis that all instruments are valid. Here the Sargan statistic is 1.25 (p = 0.2639), so the single overidentifying restriction is not rejected. A rejection would have indicated that the instruments are not satisfying the required orthogonality conditions — either because an instrument is not truly exogenous, or because it is incorrectly excluded from the regression. The test is a joint test of instrument validity and correct model specification (Baum, Schaffer & Stillman, 2003, pp. 16–17).
The test exists only when the model is overidentified; with exact
identification there are no testable restrictions. It has low power when
instruments are weak, and no power at all against violations that leave
every instrument consistent for the same wrong parameter value, so a
failure to reject does not by itself establish validity (see
?ivreg2 for the fuller treatment).
To test a subset of instruments while maintaining the rest,
use the orthog argument — see
vignette("advanced-iv") for details.
Endogeneity test (C-statistic)
The endogeneity test (also called the C-statistic or
difference-in-Sargan test) asks whether the regressors treated as
endogenous are actually endogenous. The null hypothesis is that they are
exogenous. For the just-identified fit above, the statistic is 1.17 (p =
0.2786): we cannot reject that educ is exogenous. In that
case OLS may be preferred because it is more efficient — this fit is a
live example of the trade-off, since the IV point estimate is similar to
OLS but far less precise.
The test maintains instrument validity under both hypotheses, so it
is uninformative about endogeneity if the instruments are themselves
invalid, and it shares the low power under weak instruments noted above.
Using its result to choose between OLS and IV is a pre-test whose
selection step can badly distort the size of subsequent inference
(Guggenberger, 2010); see ?ivreg2 and Hayashi (2000,
pp. 218–221, 232–234) for the underlying theory.
Stata’s ivreg2 computes this test only when
endog() is requested, whereas ivreg2r reports
it automatically for all endogenous regressors; use the
endog argument to test a specific subset (e.g.,
endog = "educ").
Anderson-Rubin test
The Anderson-Rubin (1949) test provides inference on the endogenous regressors that remains valid even when instruments are weak. Unlike the standard Wald or t-test on 2SLS coefficients — which can be severely distorted by weak instruments — the AR test controls size whether instruments are strong or weak, under the model’s maintained error assumptions.
The null hypothesis is that the coefficients on the endogenous regressors are jointly zero and the overidentifying restrictions hold. When the model is overidentified, rejection could indicate either nonzero coefficients or invalid overidentifying restrictions (or both). In the just-identified case, the overidentifying restrictions are trivially satisfied and the test is purely about the coefficients.
This serves as a useful cross-check: if the standard t-test says an
endogenous regressor is significant but the AR test does not reject,
weak instruments may be distorting inference. In the running example the
two tests agree but the gap is visible: the conventional z-test on
educ gives p = 0.0164, while the Anderson-Rubin chi-squared
test gives p = 0.0196 — still a rejection at the 5% level, but a weaker
one, consistent with the borderline first stage.
Robustness to weak instruments comes at a price: as instruments
weaken, the power of the AR test declines — Baum, Schaffer &
Stillman (2007, p. 491) describe this as an intuitively appealing
feature, since weak instruments should make confident inference
harder. In overidentified models the AR chi-squared statistic has L1
degrees of freedom (L1 = number of excluded instruments), so power also
falls as instruments are added without strengthening identification.
More powerful weak-instrument-robust procedures of the conditional
likelihood ratio type exist for those cases;
vignette("advanced-iv") discusses what this package does
and does not offer and names software that constructs
weak-instrument-robust confidence sets.
The Stock-Wright (2000) S statistic tests the same joint null
hypothesis using a GMM-distance formulation. It is also automatically
computed. See vignette("advanced-iv") for more on
weak-instrument-robust inference.
First-stage diagnostics
The summary() output reports a table of first-stage
diagnostics for each endogenous variable. Fitting with
first_stage = TRUE additionally stores the underlying
first-stage regressions, which first_stage() returns as a
named list — one ivreg2_first_stage object per endogenous
regressor, each supporting summary(), coef(),
vcov(), tidy(), and glance():
fit_fs <- ivreg2(iv_formula, data = card, first_stage = TRUE)
fs <- first_stage(fit_fs)
summary(fs$educ)
#>
#> First-stage regression: educ ~ instruments
#> Observations: 3,010
#> VCV type: iid
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 16.6382529 0.2406297 69.145 < 2e-16 ***
#> exper -0.4125334 0.0336996 -12.241 < 2e-16 ***
#> expersq 0.0008686 0.0016504 0.526 0.598728
#> black -0.9355287 0.0937348 -9.981 < 2e-16 ***
#> smsa 0.4021825 0.1048112 3.837 0.000127 ***
#> south -0.0516126 0.1354284 -0.381 0.703152
#> smsa66 0.0254805 0.1057692 0.241 0.809644
#> reg662 -0.0786363 0.1871154 -0.420 0.674329
#> reg663 -0.0279390 0.1833745 -0.152 0.878913
#> reg664 0.1171820 0.2172531 0.539 0.589665
#> reg665 -0.2726165 0.2184204 -1.248 0.212082
#> reg666 -0.3028147 0.2370712 -1.277 0.201590
#> reg667 -0.2168177 0.2343879 -0.925 0.355021
#> reg668 0.5238914 0.2674749 1.959 0.050246 .
#> reg669 0.2102710 0.2024568 1.039 0.299076
#> nearc4 0.3198989 0.0878638 3.641 0.000276 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> ---
#> Root MSE: 1.9405
#> F(1, 2994) = 13.26 (p = 0.0003)
#> Partial R2: 0.0044
#> Shea PR2: 0.0044The headline number is the partial F-statistic of the excluded
instruments, the standard measure of instrument relevance. With one
endogenous regressor and one instrument it equals the Cragg-Donald Wald
F reported above (13.26 here), so the borderline weak-identification
reading carries over directly. The tidy() method returns
the same fit as a coefficient tibble for use in tables:
tidy(fs$educ)
#> # A tibble: 16 × 7
#> term estimate std.error statistic p.value conf.low conf.high
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 (Intercept) 16.6 0.241 69.1 0 16.2 17.1
#> 2 exper -0.413 0.0337 -12.2 1.17e-33 -0.479 -0.346
#> 3 expersq 0.000869 0.00165 0.526 5.99e- 1 -0.00237 0.00410
#> 4 black -0.936 0.0937 -9.98 4.24e-23 -1.12 -0.752
#> 5 smsa 0.402 0.105 3.84 1.27e- 4 0.197 0.608
#> 6 south -0.0516 0.135 -0.381 7.03e- 1 -0.317 0.214
#> 7 smsa66 0.0255 0.106 0.241 8.10e- 1 -0.182 0.233
#> 8 reg662 -0.0786 0.187 -0.420 6.74e- 1 -0.446 0.288
#> 9 reg663 -0.0279 0.183 -0.152 8.79e- 1 -0.387 0.332
#> 10 reg664 0.117 0.217 0.539 5.90e- 1 -0.309 0.543
#> 11 reg665 -0.273 0.218 -1.25 2.12e- 1 -0.701 0.156
#> 12 reg666 -0.303 0.237 -1.28 2.02e- 1 -0.768 0.162
#> 13 reg667 -0.217 0.234 -0.925 3.55e- 1 -0.676 0.243
#> 14 reg668 0.524 0.267 1.96 5.02e- 2 -0.000562 1.05
#> 15 reg669 0.210 0.202 1.04 2.99e- 1 -0.187 0.607
#> 16 nearc4 0.320 0.0879 3.64 2.76e- 4 0.148 0.492The remaining columns are per-regressor diagnostics that become
informative only with several endogenous regressors: Shea’s (1997)
partial R-squared adjusts for intercorrelation among the instruments,
while the Sanderson-Windmeijer (2016) and Angrist-Pischke (2009)
conditional F statistics assess each endogenous regressor’s
identification given the others. With a single endogenous regressor the
two conditional F statistics collapse to the ordinary first-stage F, and
Shea’s partial R-squared to the ordinary partial R-squared. See
?ivreg2 for their definitions and ?first_stage
for the stored per-regressor regressions.
Robust and clustered inference
Heteroskedasticity-robust standard errors
Use vcov = "robust" for White (1980)
heteroskedasticity-robust standard errors. Add small = TRUE
for a finite-sample correction (equivalent to Stata’s
robust small):
fit_robust <- ivreg2(iv_formula, data = card, vcov = "robust", small = TRUE)
summary(fit_robust)
#>
#> 2SLS Estimation
#>
#> Call:
#> ivreg2(formula = iv_formula, data = card, vcov = "robust", small = TRUE)
#>
#> Observations: 3,010
#> VCV type: Robust, small-sample corrected
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 3.6661519 0.9109598 4.024 5.85e-05 ***
#> educ 0.1315038 0.0541436 2.429 0.015208 *
#> exper 0.1082711 0.0234089 4.625 3.90e-06 ***
#> expersq -0.0023349 0.0003488 -6.695 2.57e-11 ***
#> black -0.1467758 0.0525019 -2.796 0.005213 **
#> smsa 0.1118084 0.0311448 3.590 0.000336 ***
#> south -0.1446715 0.0291429 -4.964 7.28e-07 ***
#> smsa66 0.0185311 0.0205651 0.901 0.367610
#> reg662 0.1007677 0.0365488 2.757 0.005867 **
#> reg663 0.1482588 0.0355971 4.165 3.20e-05 ***
#> reg664 0.0498971 0.0436162 1.144 0.252714
#> reg665 0.1462719 0.0492259 2.971 0.002988 **
#> reg666 0.1629029 0.0517655 3.147 0.001666 **
#> reg667 0.1345722 0.0505567 2.662 0.007814 **
#> reg668 -0.0830770 0.0572432 -1.451 0.146801
#> reg669 0.1078142 0.0410761 2.625 0.008716 **
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> ---
#> R-squared: 0.2382
#> Adj. R-squared: 0.2343
#> F(15, 2994): 55.8 (p < 2.2e-16)
#> Root MSE: 0.3883
#>
#> Underidentification test (Kleibergen-Paap rk LM statistic):
#> Chi-sq(1) = 14.03 (p = 0.0002)
#>
#> Weak identification test:
#> Cragg-Donald Wald F: 13.26
#> Kleibergen-Paap rk Wald F: 14.14
#> (Stock-Yogo critical values are for iid errors)
#> Stock-Yogo critical values (IV size):
#> 10% maximal IV size 16.38
#> 15% maximal IV size 8.96
#> 20% maximal IV size 6.66
#> 25% maximal IV size 5.53
#>
#> Overidentification test (Hansen J): (equation exactly identified)
#>
#> Weak-instrument-robust inference:
#> H0: B1=0 and orthogonality conditions are valid
#> Anderson-Rubin Wald F(1,2994) = 5.76 (p = 0.0164)
#> Anderson-Rubin Wald Chi-sq(1) = 5.80 (p = 0.0161)
#> Stock-Wright LM S Chi-sq(1) = 5.83 (p = 0.0157)
#>
#> Endogeneity test:
#> Chi-sq(1) = 1.22 (p = 0.2696)
#> Tested: educ
#>
#> First-stage diagnostics:
#> Endogenous F-stat p-value Partial R2 Shea PR2 SW F AP F
#> educ 14.14 0.0002 0.0044 0.0044 14.14 14.14
#>
#> Instrumented: educ
#> Included instruments: exper, expersq, black, smsa, south, smsa66, reg662, reg663, reg664, reg665, reg666, reg667, reg668, reg669
#> Excluded instruments: nearc4Notice that the diagnostics automatically adapt. The underidentification test is now the Kleibergen-Paap rk LM statistic instead of the Anderson LM statistic. In the weak-identification block, the Kleibergen-Paap rk Wald F (14.14 here) is reported alongside the Cragg-Donald Wald F (13.26), which remains in the output for reference — only the rk statistic is valid under non-i.i.d. errors. In overidentified models the Hansen J replaces the Sargan statistic (this fit is exactly identified, so the line reads “(equation exactly identified)”).
The small = TRUE option applies finite-sample
corrections throughout: t-statistics and F-tests replace z-statistics
and chi-squared tests.
Cluster-robust standard errors
When observations are correlated within groups (e.g., repeated
observations on the same individual in panel data), use the
clusters argument. Panel data is the natural home of
clustering, so we switch here to the NLS young women’s panel
(nlswork) and regress log wages on grade, age, total
labor-market experience, and job tenure, clustering on the individual
(idcode). The example is ordinary least squares with no
instruments; the clusters argument behaves identically once
the formula gains endogenous and excluded-instrument parts, and the
clustered-IV demonstrations live in the other two vignettes.
data(nlswork)
fit_cluster <- ivreg2(
ln_wage ~ grade + age + ttl_exp + tenure,
data = nlswork, clusters = ~ idcode
)
summary(fit_cluster)
#>
#> OLS Estimation
#>
#> Call:
#> ivreg2(formula = ln_wage ~ grade + age + ttl_exp + tenure, data = nlswork,
#> clusters = ~idcode)
#>
#> Observations: 28,099
#> VCV type: Cluster-robust
#> Clusters: 4,697 (idcode)
#>
#> Coefficients:
#> Estimate Std. Error z value Pr(>|z|)
#> (Intercept) 0.6518251 0.0337636 19.306 < 2e-16 ***
#> grade 0.0744171 0.0021613 34.432 < 2e-16 ***
#> age -0.0052630 0.0009445 -5.572 2.52e-08 ***
#> ttl_exp 0.0295501 0.0018370 16.086 < 2e-16 ***
#> tenure 0.0195170 0.0016316 11.962 < 2e-16 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> ---
#> R-squared: 0.3170
#> Adj. R-squared: 0.3169
#> Wald chi2(4): 966.0 (p < 2.2e-16)
#> Root MSE: 0.3949Supplying clusters selects the cluster-robust VCE
automatically, without setting vcov. To see how much
clustering changes the standard error on grade, we compare
it against a classical (i.i.d.) fit on the same data. broom’s
tidy() returns a fit’s coefficient table as a tibble,
standard errors and all; stacking the tidied i.i.d. and clustered fits
and keeping the grade row puts the two standard errors side
by side:
fit_iid <- ivreg2(ln_wage ~ grade + age + ttl_exp + tenure, data = nlswork)
grade_se <- bind_rows(iid = tidy(fit_iid), cluster = tidy(fit_cluster), .id = "vce") |>
filter(term == "grade")
grade_se
#> # A tibble: 2 × 8
#> vce term estimate std.error statistic p.value conf.low conf.high
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 iid grade 0.0744 0.00104 71.5 0 0.0724 0.0765
#> 2 cluster grade 0.0744 0.00216 34.4 8.28e-260 0.0702 0.0787Fitting on the full 28,099 observations, the cluster-robust standard
error on grade is 0.0022, versus 0.0010 under the i.i.d.
VCE. Clustering roughly doubles the standard error because wages are
serially correlated within person across the panel’s multiple survey
years, a dependence that classical and heteroskedasticity-robust
standard errors both ignore.
Cluster-robust inference is asymptotic in the number of clusters
rather than observations: with only a handful of clusters the standard
errors can be biased downward even when N is large, and
small = TRUE only partially compensates. Here the 4,697
clusters, one per individual, put us well inside the asymptotic regime.
Researchers clustering on a dozen states or regions should consider
wild-cluster bootstrap or other few-cluster methods.
When small = TRUE is added, ivreg2r applies
the standard cluster finite-sample correction factor,
(N-1)/(N-K) * M/(M-1), where M is the number of clusters,
and reports t- and F-statistics instead of z- and chi-squared
statistics.
For two-way clustering (e.g., by firm and year in a panel), use
clusters = ~ var1 + var2. See
vignette("advanced-iv") for details.
VCE option summary
vcov |
clusters |
small |
Equivalent Stata command |
|---|---|---|---|
"iid" |
— | FALSE |
ivreg2 ... |
"iid" |
— | TRUE |
ivreg2 ..., small |
"robust" |
— | FALSE |
ivreg2 ..., robust |
"robust" |
— | TRUE |
ivreg2 ..., robust small |
| — | ~ var |
FALSE |
ivreg2 ..., cluster(var) |
| — | ~ var |
TRUE |
ivreg2 ..., cluster(var) small |
When clusters is supplied, VCE is automatically
cluster-robust regardless of the vcov argument.
For HAC, AC, Kiefer, and Driscoll-Kraay VCE options, see
vignette("time-series-gmm").
Weighted estimation
ivreg2r supports Stata’s four weight types through
weight_type: sampling weights ("pweight"),
analytic weights ("aweight", the default), frequency
weights ("fweight"), and importance weights
("iweight"). All four are passed with the
weights argument. We work through two of them — sampling
weights on the genuine survey weight the Card data ship with, and
analytic weights on a grouped-data example — then summarize how the
remaining two differ.
Sampling weights (pweight)
The Card data include a genuine survey weight: weight is
the NLS sampling weight, reflecting each respondent’s probability of
selection into the survey. Probability/sampling weights (equivalent to
Stata’s [pw=varname]) are specified with
weights plus weight_type = "pweight":
fit_pw <- ivreg2(iv_formula, data = card, weights = weight, weight_type = "pweight",
vcov = "robust")
summary(fit_pw)
#>
#> 2SLS Estimation
#>
#> Call:
#> ivreg2(formula = iv_formula, data = card, weights = weight, vcov = "robust",
#> weight_type = "pweight")
#>
#> Observations: 3,010
#> VCV type: Robust
#> Weight type: pweight
#>
#> Coefficients:
#> Estimate Std. Error z value Pr(>|z|)
#> (Intercept) 3.1946899 0.9575119 3.336 0.000849 ***
#> educ 0.1578176 0.0576981 2.735 0.006234 **
#> exper 0.1210899 0.0211739 5.719 1.07e-08 ***
#> expersq -0.0023122 0.0004505 -5.132 2.87e-07 ***
#> black -0.1461836 0.0505733 -2.891 0.003846 **
#> smsa 0.0919528 0.0335047 2.744 0.006061 **
#> south -0.1085573 0.0348286 -3.117 0.001828 **
#> smsa66 0.0309925 0.0223835 1.385 0.166171
#> reg662 0.0972339 0.0373200 2.605 0.009176 **
#> reg663 0.1436910 0.0368092 3.904 9.47e-05 ***
#> reg664 0.0378907 0.0463862 0.817 0.414013
#> reg665 0.1199726 0.0530193 2.263 0.023647 *
#> reg666 0.1372865 0.0604205 2.272 0.023075 *
#> reg667 0.1071151 0.0534122 2.005 0.044916 *
#> reg668 -0.0902232 0.0610340 -1.478 0.139343
#> reg669 0.0999564 0.0447433 2.234 0.025483 *
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> ---
#> R-squared: 0.1251
#> Adj. R-squared: 0.1208
#> Wald chi2(15): 36.1 (p < 2.2e-16)
#> Root MSE: 0.4054
#>
#> Underidentification test (Kleibergen-Paap rk LM statistic):
#> Chi-sq(1) = 12.85 (p = 0.0003)
#>
#> Weak identification test:
#> Cragg-Donald Wald F: 15.85
#> Kleibergen-Paap rk Wald F: 12.96
#> (Stock-Yogo critical values are for iid errors)
#> Stock-Yogo critical values (IV size):
#> 10% maximal IV size 16.38
#> 15% maximal IV size 8.96
#> 20% maximal IV size 6.66
#> 25% maximal IV size 5.53
#>
#> Overidentification test (Hansen J): (equation exactly identified)
#>
#> Weak-instrument-robust inference:
#> H0: B1=0 and orthogonality conditions are valid
#> Anderson-Rubin Wald F(1,2994) = 7.59 (p = 0.0059)
#> Anderson-Rubin Wald Chi-sq(1) = 7.63 (p = 0.0058)
#> Stock-Wright LM S Chi-sq(1) = 7.82 (p = 0.0052)
#>
#> Endogeneity test:
#> Chi-sq(1) = 2.43 (p = 0.1189)
#> Tested: educ
#>
#> First-stage diagnostics:
#> Endogenous F-stat p-value Partial R2 Shea PR2 SW F AP F
#> educ 12.96 0.0003 0.0053 0.0053 12.96 12.96
#>
#> Instrumented: educ
#> Included instruments: exper, expersq, black, smsa, south, smsa66, reg662, reg663, reg664, reg665, reg666, reg667, reg668, reg669
#> Excluded instruments: nearc4Because pweights describe the sampling design rather than the error
variance, valid standard errors must be robust: ivreg2r
forces a robust VCE whenever weight_type = "pweight",
regardless of the vcov setting, exactly as Stata does for
[pw=]. We pass vcov = "robust" explicitly
above; leaving vcov at its default "iid" would
trigger the same forced override, with a warning noting it. The weighted
point estimate answers a population-level question — what is the return
to schooling in the population the NLS sample was drawn from — whereas
the unweighted fit describes the sample.
Analytic weights (aweight)
An analytic weight is inversely proportional to an observation’s
variance. The textbook case is grouped data: each row is a cell mean,
weighted by the number of individuals that went into the cell, and the
defining property is that a weighted regression on the cell means
reproduces the coefficients of the individual-level regression. We can
watch that identity hold. Collapse the individuals to the cells of three
binary covariates, taking each cell’s mean log wage and its size —
group_by() |> summarize() is Stata’s
collapse (mean) lwage (count) n = lwage, by(black smsa south):
cells <- card |>
group_by(black, smsa, south) |>
summarize(lwage = mean(lwage), n = n(), .groups = "drop")
micro <- ivreg2(lwage ~ black + smsa + south, data = card)
grouped <- ivreg2(lwage ~ black + smsa + south, data = cells,
weights = n, weight_type = "aweight")
all.equal(coef(micro), coef(grouped))
#> [1] TRUEThe cell means are computed in double precision, so nothing is lost
in the collapse, and the two coefficient vectors agree to numerical
tolerance: aweight on the cell means recovers exactly what
the individual-level regression would have given.
The other weight types
The remaining two types are passed the same way —
weights = plus weight_type = — and differ only
in what the weight means:
-
Frequency weights
(
weight_type = "fweight", Stata’s[fw=]) record how many identical observations a row stands for, so a row with weight 3 counts as three copies and the sample size becomes the sum of the weights:ivreg2(y ~ x, data = d, weights = count, weight_type = "fweight"). They obey an identity of the same kind as analytic weights: an fweighted fit reproduces the fit on the fully expanded rows, standard errors and sample size included. The validation article checks that identity against Stata. -
Importance weights
(
weight_type = "iweight", Stata’s[iw=]) attach an arbitrary multiplier to each observation without a probabilistic interpretation. Like frequency weights they are not normalized, so N becomes the sum of the weights, but they are restricted to the classical i.i.d. VCE and are incompatible with robust, cluster, HAC, and GMM estimation. They exist mainly for building weighted computations on top ofivreg2r.
See ?ivreg2 for the precise rules.
For aweights and pweights the weights are normalized internally to
sum to N, following Stata, so coefficients, standard errors, and test
statistics do not depend on the scale of the weights. One consequence is
that for these two types sigma (the Root MSE) differs from
lm()’s by a factor of sqrt(N / sum(w)),
because lm() uses the raw weights.
Beyond 2SLS
This vignette focuses on 2SLS, but ivreg2r also supports
LIML, Fuller, and k-class estimation via the method,
fuller, and kclass arguments. LIML has smaller
approximate bias than 2SLS when there are many or weak instruments.
Fuller’s (1977) modified LIML further improves on LIML by having finite
moments. These finite-sample advantages are established under i.i.d.
errors; neither estimator is robust to violations of that assumption
(Baum, Schaffer & Stillman, 2007, pp. 478–479). See
vignette("advanced-iv") for examples and comparisons.
Tidyverse workflows
ivreg2 objects integrate with the tidyverse through
tidy(), glance(), and
augment().
Coefficient table
tidy() returns a tibble of coefficient estimates with
standard errors, test statistics, p-values, and confidence
intervals:
tidy(fit_iv)
#> # A tibble: 16 × 7
#> term estimate std.error statistic p.value conf.low conf.high
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 (Intercept) 3.67 0.922 3.97 7.05e- 5 1.86 5.47
#> 2 educ 0.132 0.0548 2.40 1.64e- 2 0.0241 0.239
#> 3 exper 0.108 0.0236 4.59 4.46e- 6 0.0620 0.155
#> 4 expersq -0.00233 0.000333 -7.02 2.22e-12 -0.00299 -0.00168
#> 5 black -0.147 0.0538 -2.73 6.33e- 3 -0.252 -0.0414
#> 6 smsa 0.112 0.0316 3.54 3.99e- 4 0.0499 0.174
#> 7 south -0.145 0.0272 -5.32 1.06e- 7 -0.198 -0.0913
#> 8 smsa66 0.0185 0.0216 0.860 3.90e- 1 -0.0237 0.0608
#> 9 reg662 0.101 0.0376 2.68 7.34e- 3 0.0271 0.174
#> 10 reg663 0.148 0.0367 4.04 5.39e- 5 0.0763 0.220
#> 11 reg664 0.0499 0.0436 1.14 2.53e- 1 -0.0356 0.135
#> 12 reg665 0.146 0.0469 3.12 1.83e- 3 0.0543 0.238
#> 13 reg666 0.163 0.0518 3.15 1.65e- 3 0.0614 0.264
#> 14 reg667 0.135 0.0493 2.73 6.31e- 3 0.0380 0.231
#> 15 reg668 -0.0831 0.0592 -1.40 1.60e- 1 -0.199 0.0329
#> 16 reg669 0.108 0.0417 2.59 9.73e- 3 0.0261 0.190For the intervals alone, confint(fit_iv) returns the
same bounds as a matrix; they are based on the t-distribution when
small = TRUE was used at estimation time and on the
standard normal otherwise.
Model summary
glance() returns a single-row tibble with fit statistics
and the headline diagnostic tests (weak identification,
underidentification, overidentification) — a compact set chosen so that
model-comparison tables render sensibly:
glance(fit_iv)
#> # A tibble: 1 × 15
#> r.squared adj.r.squared sigma statistic p.value df df.residual nobs
#> <dbl> <dbl> <dbl> <dbl> <dbl> <int> <int> <int>
#> 1 0.238 0.234 0.387 51.0 8.58e-136 15 2994 3010
#> # ℹ 7 more variables: vcov_type <chr>, weak_id_stat <dbl>,
#> # weak_id_robust_stat <dbl>, underid_stat <dbl>, underid_p <dbl>,
#> # overid_stat <dbl>, overid_p <dbl>Diagnostic tests as data
diagnostics() returns the full set of specification
tests that summary() prints — including the Stock-Yogo
critical values — as a tibble with one row per test:
diagnostics(fit_iv)
#> # A tibble: 11 × 8
#> test test_name statistic df df2 p_value tested_vars note
#> <chr> <chr> <dbl> <int> <int> <dbl> <chr> <chr>
#> 1 underid Anderson… 13.3 1 NA 2.70e-4 NA NA
#> 2 weak_id Cragg-Do… 13.3 NA NA NA NA NA
#> 3 sy_iv_size_10 Stock-Yo… 16.4 NA NA NA NA NA
#> 4 sy_iv_size_15 Stock-Yo… 8.96 NA NA NA NA NA
#> 5 sy_iv_size_20 Stock-Yo… 6.66 NA NA NA NA NA
#> 6 sy_iv_size_25 Stock-Yo… 5.53 NA NA NA NA NA
#> 7 overid Sargan 0 0 NA NA NA NA
#> 8 anderson_rubin_f Anderson… 5.42 1 2994 2.00e-2 NA NA
#> 9 anderson_rubin_ch… Anderson… 5.44 1 NA 1.96e-2 NA NA
#> 10 stock_wright Stock-Wr… 5.43 1 NA 1.97e-2 NA NA
#> 11 endogeneity Endogene… 1.17 1 NA 2.79e-1 educ NAThe test column holds stable keys, so pulling one test
out for a table or a threshold comparison is a one-line
filter(test == "weak_id"). Tests you request through
endog, orthog, or redundant —
Stata’s endog(), orthog(), and
redundant() options — appear as additional rows.
Augmented data
augment() returns the original data with fitted values
and residuals appended:
augment(fit_iv) |> head()
#> # A tibble: 6 × 19
#> lwage exper expersq black smsa south smsa66 reg662 reg663 reg664 reg665
#> <dbl> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
#> 1 6.31 16 256 1 1 0 1 0 0 0 0
#> 2 6.18 9 81 0 1 0 1 0 0 0 0
#> 3 6.58 16 256 0 1 0 1 0 0 0 0
#> 4 5.52 10 100 0 1 0 1 1 0 0 0
#> 5 6.59 16 256 0 1 0 1 1 0 0 0
#> 6 6.21 8 64 0 1 0 1 1 0 0 0
#> # ℹ 8 more variables: reg666 <int>, reg667 <int>, reg668 <int>, reg669 <int>,
#> # educ <int>, nearc4 <int>, .fitted <dbl>, .resid <dbl>Stata migration quick reference
Estimation basics and accessors
| Task | Stata | R (ivreg2r) |
|---|---|---|
| Basic IV | ivreg2 y x (endo = z) |
ivreg2(y ~ x | endo | z, data = d) |
| Extra instruments, no endogenous regressor | ivreg2 y x (=z1 z2) |
ivreg2(y ~ x | 0 | z1 + z2, data = d) (the
0 marks an empty endogenous group) |
| Lag / difference |
L.x / D.x
|
l(x, 1) / d(x, 1) (requires
tvar, plus ivar for panels) |
| Coefficients | e(b) |
coef(fit) |
| VCV matrix | e(V) |
vcov(fit) |
| Residuals | predict resid, resid |
residuals(fit) |
| Fitted values | predict yhat |
fitted(fit) |
| Prediction SE | predict s, stdp |
predict(fit, se.fit = TRUE) |
| Confidence intervals | — | confint(fit) |
| Tidy coef table | — | tidy(fit) |
| Summary statistics | ereturn list |
glance(fit) |
| Diagnostics | Displayed after estimation | Displayed by summary(fit); as a tibble via
diagnostics(fit)
|
Estimators
| Task | Stata | R (ivreg2r) |
|---|---|---|
| LIML | ivreg2 ..., liml |
ivreg2(..., method = "liml") |
| Fuller(1) | ivreg2 ..., fuller(1) |
ivreg2(..., fuller = 1) |
| k-class | ivreg2 ..., kclass(0.5) |
ivreg2(..., kclass = 0.5) |
| COVIV | ivreg2 ..., liml coviv |
ivreg2(..., method = "liml", coviv = TRUE) |
| GMM2S | ivreg2 ..., gmm2s |
ivreg2(..., method = "gmm2s") |
| CUE | ivreg2 ..., cue |
ivreg2(..., method = "cue") |
| Evaluate CUE at fixed b | ivreg2 ..., b0(bmat) |
ivreg2(..., b0 = c(...)) |
| User W matrix | ivreg2 ..., wmatrix(name) |
ivreg2(..., wmatrix = W) |
| User S matrix | ivreg2 ..., smatrix(name) |
ivreg2(..., smatrix = S) |
| Moment covariance / weight matrix |
e(S) / e(W)
|
fit$S / fit$W
|
Variance estimation and clustering
| Task | Stata | R (ivreg2r) |
|---|---|---|
| Robust SEs | ivreg2 ..., robust |
ivreg2(..., vcov = "robust") |
| Robust + small | ivreg2 ..., robust small |
ivreg2(..., vcov = "robust", small = TRUE) |
| Cluster SEs | ivreg2 ..., cluster(g) |
ivreg2(..., clusters = ~ g) |
| Cluster + small | ivreg2 ..., cluster(g) small |
ivreg2(..., clusters = ~ g, small = TRUE) |
| Two-way cluster | ivreg2 ..., cluster(g1 g2) |
ivreg2(..., clusters = ~ g1 + g2) |
| AC kernel | ivreg2 ..., kernel(bar) bw(3) |
ivreg2(..., kernel = "bartlett", bw = 3, tvar = "year") |
| HAC kernel | ivreg2 ..., robust kernel(bar) bw(3) |
ivreg2(..., vcov = "robust", kernel = "bartlett", bw = 3, tvar = "year") |
| Auto bandwidth | ivreg2 ..., kernel(bar) bw(auto) |
ivreg2(..., kernel = "bartlett", bw = "auto", tvar = "year") |
| Driscoll-Kraay | ivreg2 ..., dkraay(3) |
ivreg2(..., dkraay = 3, tvar = "year", ivar = "id") |
| Kiefer VCE | ivreg2 ..., kiefer |
ivreg2(..., kiefer = TRUE, tvar = "year", ivar = "id") |
| Stock-Watson VCE | ivreg2 ..., sw |
ivreg2(..., sw = TRUE, ivar = "id") |
| Center moments | ivreg2 ..., center |
ivreg2(..., center = TRUE) |
Weights, tests, and other options
| Task | Stata | R (ivreg2r) |
|---|---|---|
| Analytic weights | ivreg2 ... [aw=w] |
ivreg2(..., weights = w) |
| Frequency weights | ivreg2 ... [fw=w] |
ivreg2(..., weights = w, weight_type = "fweight") |
| Probability weights | ivreg2 ... [pw=w] |
ivreg2(..., weights = w, weight_type = "pweight") |
| Importance weights | ivreg2 ... [iw=w] |
ivreg2(..., weights = w, weight_type = "iweight") |
| Orthogonality test | ivreg2 ..., orthog(z1) |
ivreg2(..., orthog = c("z1")) |
| Endogeneity test | ivreg2 ..., endog(z1) |
ivreg2(..., endog = c("z1")) |
| Redundancy test | ivreg2 ..., redundant(z1) |
ivreg2(..., redundant = c("z1")) |
| DoF adjustment | ivreg2 ..., dofminus(5) |
ivreg2(..., dofminus = 5) |
| Small-sample DoF | ivreg2 ..., sdofminus(3) |
ivreg2(..., sdofminus = 3) |
| Partialling | ivreg2 ..., partial(x1) |
ivreg2(..., partial = c("x1")) |
| Partial constant / all | ivreg2 ..., partial(_cons) |
ivreg2(..., partial = "_cons") or
"_all"
|
| No partial DoF adjustment | ivreg2 ..., nopartialsmall |
ivreg2(..., nopartialsmall = TRUE) |
| Save first stage | ivreg2 ..., savefirst |
ivreg2(..., first_stage = TRUE), then
first_stage(fit)
|
| Save reduced form | ivreg2 ..., saverf |
ivreg2(..., reduced_form = "rf") (rf
displays, saverf stores) |
| Save first-stage system | ivreg2 ..., savesfirst |
ivreg2(..., reduced_form = "system")
(savesfirst is undocumented in Stata) |
| Suppress ID stats | ivreg2 ..., noid |
ivreg2(..., noid = TRUE) |
See vignette("advanced-iv") for LIML, k-class, two-way
clustering, and model comparison examples. See
vignette("time-series-gmm") for HAC/AC, GMM, CUE,
partialling, and panel VCE examples.
Intentional differences from Stata
| Area | Stata ivreg2
|
ivreg2r |
Rationale |
|---|---|---|---|
| Formula | ivreg2 y x (endo = z) |
y ~ x | endo | z |
R convention; each variable listed once |
| Numerical method | Cross-products via Mata | QR-based regression via lm.fit
|
Better conditioning for core estimation |
| Diagnostics | Some computed at post-estimation | All computed at estimation time | Returned as a tibble by diagnostics(); headline tests
also in glance()
|
| Factor variables |
i. prefix syntax |
R model.matrix() / contrasts |
R convention |
| Time-series |
tsset declares time/panel |
tvar= / ivar= arguments |
R has no tsset; explicit args |
| CUE optimizer | Mata optimize()
|
R optim() (BFGS + Nelder-Mead) |
Different optimizer, same objective |
redundant with no endogenous regressors |
Silently ignored | Warns that the test is skipped | An explicitly requested test should not disappear silently |
| Missing values in a cluster variable | Silently drops the affected observations from the estimation sample | Raises an error asking the user to drop or handle those rows explicitly | The estimation sample should never change silently |
References
- Anderson, T.W. (1951). “Estimating Linear Restrictions on Regression Coefficients for Multivariate Normal Distributions.” Annals of Mathematical Statistics, 22(3), 327–351.
- Anderson, T.W. and Rubin, H. (1949). “Estimation of the Parameters of a Single Equation in a Complete System of Stochastic Equations.” Annals of Mathematical Statistics, 20(1), 46–63.
- Angrist, J.D. and Pischke, J.-S. (2009). Mostly Harmless Econometrics. Princeton University Press.
- Baum, C.F., Schaffer, M.E., and Stillman, S. (2003). “Instrumental Variables and GMM: Estimation and Testing.” Stata Journal, 3(1), 1–31.
- Baum, C.F., Schaffer, M.E., and Stillman, S. (2007). “Enhanced Routines for Instrumental Variables/Generalized Method of Moments Estimation and Testing.” Stata Journal, 7(4), 465–506.
- Card, D. (1995). “Using Geographic Variation in College Proximity to Estimate the Return to Schooling.” In L.N. Christofides, E.K. Grant, and R. Swidinsky (Eds.), Aspects of Labour Market Behaviour: Essays in Honour of John Vanderkamp. University of Toronto Press.
- Cragg, J.G. and Donald, S.G. (1993). “Testing Identifiability and Specification in Instrumental Variable Models.” Econometric Theory, 9(2), 222–240.
- Fuller, W.A. (1977). “Some Properties of a Modification of the Limited Information Estimator.” Econometrica, 45(4), 939–953.
- Guggenberger, P. (2010). “The Impact of a Hausman Pretest on the Asymptotic Size of a Hypothesis Test.” Econometric Theory, 26(2), 369–382.
- Hansen, L.P. (1982). “Large Sample Properties of Generalized Method of Moments Estimators.” Econometrica, 50(4), 1029–1054.
- Hayashi, F. (2000). Econometrics. Princeton University Press.
- Kleibergen, F. and Paap, R. (2006). “Generalized Reduced Rank Tests Using the Singular Value Decomposition.” Journal of Econometrics, 133(1), 97–126.
- Sanderson, E. and Windmeijer, F. (2016). “A Weak Instrument F-Test in Linear IV Models with Multiple Endogenous Variables.” Journal of Econometrics, 190(2), 212–221.
- Sargan, J.D. (1958). “The Estimation of Economic Relationships Using Instrumental Variables.” Econometrica, 26(3), 393–415.
- Shea, J. (1997). “Instrument Relevance in Multivariate Linear Models: A Simple Measure.” Review of Economics and Statistics, 79(2), 348–352.
- Staiger, D. and Stock, J.H. (1997). “Instrumental Variables Regression with Weak Instruments.” Econometrica, 65(3), 557–586.
- Stock, J.H. and Wright, J.H. (2000). “GMM with Weak Identification.” Econometrica, 68(5), 1055–1096.
- Stock, J.H. and Yogo, M. (2005). “Testing for Weak Instruments in Linear IV Regression.” In D.W.K. Andrews and J.H. Stock (Eds.), Identification and Inference for Econometric Models: Essays in Honor of Thomas Rothenberg. Cambridge University Press.
- White, H. (1980). “A Heteroskedasticity-Consistent Covariance Matrix Estimator and a Direct Test for Heteroskedasticity.” Econometrica, 48(4), 817–838.
- Wooldridge, J.M. (2020). Introductory Econometrics: A Modern Approach, 7th edition. Cengage.