I run instrumental variable regression (2SLS) with ivreg
package.
library(ivreg)
as_tibble(mtcars)
model_iv <- ivreg(formula = mpg ~ disp + drat |
drat + carb,
data = mtcars)
As many other people, I am interested in the diagnostics (e.g. weak instruments, wu-hausman and sargan) attached to my model reporting.
summary(model_iv, diagnostics = TRUE)
Diagnostic tests:
df1 df2 statistic p-value
Weak instruments 1 29 8.286 0.00743 **
Wu-Hausman 1 28 11.594 0.00202 **
Sargan 0 NA NA NA
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
There is a workaround to add those to stargazer
:
R: Robust SE's and model diagnostics in stargazer table
And I found the very discussion in an issue for modelsummary
:
https://github.com/vincentarelbundock/modelsummary/issues/123
I tried the modelsummary
but it seems that the feature hasn't been implemented. Is there another package for model reporting including diagnostics for instrumental variable models?
You can easily do this with modelsummary
. Please see the detailed documentation on how to add new goodness-of-fit statistics on the website: https://vincentarelbundock.github.io/modelsummary/articles/modelsummary.html#new-models-and-custom-statistics
There are basically 3 options.
add_rows
Build your own data frame with the same number of columns as your table, and use the add_rows
argument to stick it at the bottom of the table. This allows you full control, but can be tedious. It is also quite self-explanatory, so I don’t give an example here. Just see ?modelsummary
.
metrics
argumentBehind the scenes, modelsummary
extracts goodness of fit statistics using the performance
package. That package supports a metrics="all"
argument which sometimes return more information. In this case, we can feed metrics
directly to modelsummary
and get the Wu-Haussman statistic:
library(ivreg)
library(tibble)
library(modelsummary)
model_iv <- ivreg(
formula = mpg ~ disp + drat | drat + carb,
data = mtcars)
modelsummary(model_iv, metrics = "all")
(1) | |
---|---|
(Intercept) | 51.687 |
(17.451) | |
disp | -0.072 |
(0.020) | |
drat | -4.169 |
(3.649) | |
Num.Obs. | 32 |
R2 | 0.455 |
R2 Adj. | 0.418 |
AIC | 193.3 |
BIC | 199.2 |
RMSE | 4.38 |
wu.hausman | 11.5944242731131 |
wu.hausman.p | 0.00201604586133519 |
Of course, you’ll probably want to format this statistic with the gof_map
argument to reduce the number of digits and clean up the names.
glance_custom
Finally, you can define a glance_custom.ivreg()
method to extract, format, and add the statistic automatically. There is a detailed tutorial at the link I posted above, so here’s a simple example:
glance_custom.ivreg <- function(x, ...) { # don't forget ...
s <- summary(x)$diagnostics
wi <- s[1, "statistic"]
wh <- s[2, "statistic"]
tibble(
"Weak Instrument" = round(wi, 2),
"Wu-Haussman" = round(wh, 3))
}
modelsummary(model_iv)
(1) | |
---|---|
(Intercept) | 51.687 |
(17.451) | |
disp | -0.072 |
(0.020) | |
drat | -4.169 |
(3.649) | |
Num.Obs. | 32 |
R2 | 0.455 |
R2 Adj. | 0.418 |
AIC | 193.3 |
BIC | 199.2 |
RMSE | 4.38 |
Weak Instrument | 8.29 |
Wu-Haussman | 11.594 |
All subsequent ivreg
models will automatically have this new statistic.