analyze_iv_regression

source

analyze_iv_regression(
    df,
    dv,
    endog,
    instruments,
    exog=None,
    feffects=None,
    clusters=None,
    *,
    format='gt',
)

Fit an instrumental-variables (2SLS) regression with a weak-instrument diagnostic.

Endogenous regressors are instrumented with excluded instruments while exog (included exogenous controls) and feffects (absorbed fixed effects) enter directly. The fit delegates to pyfixest’s native IV estimator, and the result carries the first-stage F statistic — the conventional check for weak instruments (a value below about 10 is the Staiger-Stock warning sign). For panel data, prefer :func:analyze_panel_iv_regression, which manages the entity/time fixed effects for you.

Parameters

Name Type Description Default
df pd.DataFrame Data frame containing the data. required
dv str Dependent (outcome) variable name. required
endog Sequence[str] | str Endogenous regressor name(s) to be instrumented. required
instruments Sequence[str] | str Excluded instrument name(s). At least as many instruments as endogenous regressors are required (the order condition); more instruments over-identify the model. required
exog Sequence[str] | None Included exogenous regressor (control) names, if any. None
feffects Sequence[str] | None Fixed-effects variable names absorbed by pyfixest. None
clusters Sequence[str] | None Cluster variable name(s) for cluster-robust standard errors. None
format Literal['gt', 'tex', 'md', 'df', 'html'] Output format for the rendered etable: "gt" (Great Tables), "tex", "md", "df" (DataFrame) or "html". 'gt'

Returns

Name Type Description
IVRegressionResult model (the fitted pyfixest IV model), etable (rendered table), df (tidy coefficient frame), the endog / instruments / exog names, and first_stage_f / first_stage_p (the first-stage weak-instrument F and p-value).

Raises

Name Type Description
ValueError If no endogenous regressor or instrument is given, or the model is under-identified (fewer instruments than endogenous regressors).
NotImplementedError If the dependent variable is non-numeric (only OLS-family IV is supported).

Examples

The canonical Acemoglu-Johnson-Robinson (2001) example: instrument average protection against expropriation risk with log settler mortality, on the 64-country base sample. The instrumented slope is the famous ≈ 0.94:

import expdpy as ex
from expdpy.data import load_colonial_origins, load_colonial_origins_data_def

df = ex.set_labels(load_colonial_origins(), load_colonial_origins_data_def())
base = df[df["base_sample"] == 1]

result = ex.analyze_iv_regression(
    base,
    dv="log_gdp_pc_1995",
    endog="expropriation_risk",
    instruments="log_settler_mortality",
)
result.etable
result.first_stage_f
print(result.interpret())
This IV (2SLS) regression instruments **expropriation_risk** with *log_settler_mortality*, relating it to **log_gdp_pc_1995**. Two-stage least squares isolates the part of the endogenous regressor that moves with the instruments, purging the endogeneity that biases ordinary least squares.

- **expropriation_risk** (instrumented): a one-unit increase is associated with log_gdp_pc_1995 that is 0.944 higher (statistically significant at the 1% level).

The first-stage F is 22.9 — **above** the conventional weak-instrument threshold of 10, so the instruments are reasonably strong.
IV is trustworthy only when the instruments are both **relevant** (a strong first stage) and **excludable** — related to log_gdp_pc_1995 solely through the instrumented regressor.

_These are associations, not causal effects. A causal reading needs a research design — see `explain('correlation_vs_causation')`._