PanelRegression#
- class causalpy.experiments.panel_regression.PanelRegression[source]#
Panel regression with fixed effects estimation.
Enables panel-aware visualization and diagnostics, with support for both dummy variable and within-transformation approaches to fixed effects.
- Parameters:
data (pd.DataFrame) – A pandas dataframe with panel data. Each row is an observation for a unit at a time period.
formula (str) – A statistical model formula using patsy syntax. For dummy variable approach, include C(unit_var) in the formula. For within transformation, do NOT include C(unit_var) as it will be automatically removed.
unit_fe_variable (str) – Column name for the unit identifier (e.g., “state”, “id”, “country”).
time_fe_variable (str, optional) – Column name for the time identifier (e.g., “year”, “wave”, “period”). If provided, time fixed effects will be included. Default is None.
fe_method ({"dummies", "within"}, default="dummies") –
Method for handling fixed effects: - “dummies”: Use dummy variables (C(unit) in formula). Gets individual
unit effect estimates but creates N-1 dummy columns. Best for small N.
”within”: Use within transformation (demeaning). Scales to large N but doesn’t directly estimate individual unit effects.
model (PyMCModel or RegressorMixin, optional) – A PyMC (Bayesian) or sklearn (OLS) model. If None, a model must be provided.
Examples
Small panel with dummy variables:
>>> import causalpy as cp >>> import pandas as pd >>> # Create small panel: 10 units, 20 time periods >>> np.random.seed(42) >>> units = [f"unit_{i}" for i in range(10)] >>> periods = range(20) >>> data = pd.DataFrame( ... [ ... { ... "unit": u, ... "time": t, ... "treatment": int(t >= 10 and u in units[:5]), ... "x1": np.random.randn(), ... "y": np.random.randn(), ... } ... for u in units ... for t in periods ... ] ... ) >>> result = cp.PanelRegression( ... data=data, ... formula="y ~ C(unit) + C(time) + treatment + x1", ... unit_fe_variable="unit", ... time_fe_variable="time", ... fe_method="dummies", ... model=cp.pymc_models.LinearRegression( ... sample_kwargs={"random_seed": 42, "progressbar": False} ... ), ... )
Large panel with within transformation:
>>> # Create larger panel: 1000 units, 10 time periods >>> np.random.seed(42) >>> units = [f"unit_{i}" for i in range(1000)] >>> periods = range(10) >>> data = pd.DataFrame( ... [ ... { ... "unit": u, ... "time": t, ... "treatment": int(t >= 5), ... "x1": np.random.randn(), ... "y": np.random.randn(), ... } ... for u in units ... for t in periods ... ] ... ) >>> result = cp.PanelRegression( ... data=data, ... formula="y ~ treatment + x1", # No C(unit) needed ... unit_fe_variable="unit", ... time_fe_variable="time", ... fe_method="within", ... model=cp.pymc_models.LinearRegression( ... sample_kwargs={"random_seed": 42, "progressbar": False} ... ), ... )
Notes
The within transformation demeans all numeric and boolean variables by group, which removes time-invariant confounders but also drops time-invariant covariates from the model. For the dummy approach, individual unit effects can be extracted from the coefficients. For the within approach, unit effects can be recovered post-hoc using the stored group means (
_group_means), which are always computed from the original (pre-demeaning) data.Two-way fixed effects (unit + time) control for both unit-specific and time-specific unobserved heterogeneity. This is the standard approach in difference-in-differences estimation.
Balanced panels: When both unit and time fixed effects are requested with
fe_method="within", the sequential demeaning (first by unit, then by time) is algebraically equivalent to the standard two-way within transformation only for balanced panels (every unit observed in every period). For unbalanced panels, iterative alternating demeaning would be needed for exact convergence; the single-pass approximation may introduce small biases.Methods
PanelRegression.__init__(data, formula, ...)Run the experiment algorithm: fit the model.
PanelRegression.effect_summary(*[, window, ...])Generate a decision-ready summary of causal effects.
PanelRegression.fit(*args, **kwargs)PanelRegression.get_plot_data(*args, **kwargs)Recover the data of an experiment along with the prediction and causal impact information.
PanelRegression.get_plot_data_bayesian(**kwargs)Get plot data for Bayesian model.
PanelRegression.get_plot_data_ols(**kwargs)Get plot data for OLS model.
Validate input parameters.
PanelRegression.plot(*args, **kwargs)Plot the model.
PanelRegression.plot_coefficients([var_names])Plot coefficient estimates with credible/confidence intervals.
PanelRegression.plot_residuals([kind])Plot residual diagnostics.
PanelRegression.plot_trajectories([units, ...])Plot unit-level time series trajectories.
Plot distribution of unit fixed effects.
PanelRegression.print_coefficients([round_to])Ask the model to print its coefficients.
PanelRegression.summary([round_to])Print a summary of the panel regression results.
Attributes
idataReturn the InferenceData object of the model.
supports_bayessupports_olslabels- __init__(data, formula, unit_fe_variable, time_fe_variable=None, fe_method='dummies', model=None, **kwargs)[source]#
- classmethod __new__(*args, **kwargs)#