FE
FE estimates a one-way (entity) or two-way (entity + time) fixed effects ("within") panel
regression. It shares the general API shape with OLS (data/y/x/options
constructor, .fit()), but entity (and optionally time) is a required argument rather than
an option, since a fixed effects model has no meaning without a panel structure. There is no
intercept: the within transformation removes it structurally, so FEOptions has no
include_intercept field and FEResults.param_names never includes "const".
One-way vs. two-way
Whether the model is one-way (entity only) or two-way (entity + time) is controlled entirely by
FEOptions.time: None (default) gives one-way, any column name gives two-way. Two-way fixed
effects require a balanced panel; an unbalanced panel with time set raises a
ValidationError. One-way fixed effects support unbalanced panels without restriction.
FEResults.n_periods is the number of unique time periods for two-way effects and None for one-way.
Standard error types
FEOptions.cov_type defaults to "cluster" (clustered on entity) rather than "classical" —
a deliberate departure from OLS's default,
following the same convention as fixest: panel data almost always has within-entity serial
correlation, and defaulting to a robust-but-not-clustered type would understate it. Supported
values are "classical", "hc1", "hc2", "hc3", "cluster", and "dk" — "hc0" is not
supported (neither linearmodels nor fixest offer it for panel/FE models).
"dk" is not the same Newey-West estimator as OLS's: it is a Driscoll-Kraay panel HAC
estimator (fixest's vcov="DK", Stata's xtscc), which is robust to both cross-entity and
within-entity correlation. FEOptions.dk_time is required with "dk": it names the column that
defines the time periods. It is never taken from FEOptions.time, which only sets the two-way
fixed effects, so the fixed effects and the HAC kernel may use different time granularities (for
example quarterly fixed effects with yearly periods for the kernel). FEOptions.dk_bandwidth sets
the kernel bandwidth explicitly; when omitted it is chosen automatically from the number of
unique time periods. The bandwidth actually used is reported as FEResults.dk_bandwidth_used
(None unless cov_type="dk").
The small-sample corrections and the degrees of freedom of the t and F tests follow fixest's
ssc() defaults: "cluster" scales by G/(G-1) · (n-1)/(n-K) and uses G - 1 degrees of
freedom (G = number of clusters), "dk" uses T/(T-1) with T = number of time periods in
place of G and T - 1 degrees of freedom, and the other types use df_resid. These differ
from linearmodels, which does not apply the G/(G-1) factor. See
Inference conventions for the full table.
Panel R²
FEResults reports three separate R² values instead of OLS's single r_squared/adj_r_squared
pair, since "the" R² is not well-defined once fixed effects are involved:
r_squared_within (based on the within-transformed variables), r_squared_between (based on
entity-mean variables), and r_squared_overall (based on the untransformed variables).
Recovering the fixed effects
The fixed effects themselves (α_i for entity, γ_t for time) are not part of the fit()
result; call FEResults.fixed_effects() separately. One-way returns dict[str, float] keyed by
entity id. Two-way returns dict[str, dict[str, float]] with top-level keys "entity" and
"time" — the two-way case has a normalization choice (which effect absorbs the overall level),
so its values do not always match fixest::fixef() numerically; see the method's docstring for
the exact convention.
econometricsmodels.FE(data, y, x, entity, options=None)
Fixed effects (within) panel regression estimator.
Supports one-way (entity) and two-way (entity + time) fixed
effects, selected via FEOptions.time (docs/spec/fe-spec.md
section 1).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
DataFrame
|
A polars DataFrame containing the dependent variable, independent variables, entity identifier, and (if specified) time/cluster/HAC time columns. |
required |
y
|
str
|
Column name of the dependent variable. |
required |
x
|
list[str]
|
List of column names of the independent variables. Must contain at least one column name. |
required |
entity
|
str
|
Column name of the entity (individual/panel unit) identifier. |
required |
options
|
FEOptions | None
|
Estimation options. Defaults to |
None
|
Examples:
>>> import polars as pl
>>> from econometricsmodels import FE
>>> df = pl.DataFrame(
... {
... "y": [1.0, 2.0, 3.0, 4.0, 5.0, 6.0],
... "x1": [2.0, 4.0, 1.0, 5.0, 3.0, 6.0],
... "id": ["a", "a", "b", "b", "c", "c"],
... }
... )
>>> result = FE(df, y="y", x=["x1"], entity="id").fit()
>>> result.params["x1"]
fit()
Estimate the FE model.
Returns:
| Type | Description |
|---|---|
FEResults
|
The estimation results. |
Raises:
| Type | Description |
|---|---|
TypeError
|
An argument has the wrong type (for example
|
ValidationError
|
The input or options are invalid ( |
ComputationError
|
A problem was detected during
computation (e.g. a singular within-transformed design
matrix). A subclass of |
econometricsmodels.FEOptions
Estimation options for FE (fixed effects panel regression).
See docs/spec/panel-common.md for the rationale behind each field's
meaning and default value.
cluster
property
Column name to use as the cluster group key when cov_type="cluster". When
None, the entity argument's column is used automatically. Specifying it with
any other cov_type raises ValidationError.
confidence_level
property
Confidence level for confidence intervals, in the range (0, 1). Defaults to 0.95 (a 95% confidence interval).
cov_type
property
Standard error type: one of "classical", "hc1", "hc2", "hc3", "cluster", "dk". Case-insensitive. Unlike OLS/WLS/IV, "hc0" is not supported (neither linearmodels nor fixest offer it for panel/FE regressions).
dk_bandwidth
property
Bandwidth for Driscoll-Kraay HAC when cov_type="dk". When None, computed
automatically via floor(4*(t/100)^(2/9)) (t = number of unique time periods).
Specifying it with any other cov_type raises ValidationError.
dk_time
property
Column name that defines the time periods of the Driscoll-Kraay HAC, independent
of time (time and dk_time serve different purposes; see the module
docstring). Required when cov_type="dk", in one-way and two-way models alike:
leaving it unset raises ValidationError, and time is not used instead. With
two-way effects the HAC may use a different time granularity from the fixed
effects. It may not be the same column as y or entity (ValidationError), but
may be one of the regressors or the same column as time. Specifying it with any
other cov_type raises ValidationError. The periods are ordered by the values of the column (see time).
time
property
Column name of the time identifier. When set, requests two-way fixed effects
(entity + time); when None (default), one-way (entity only). It only defines the
fixed-effects structure: it is never used as the Driscoll-Kraay time periods (set
dk_time for that). The periods are ordered by the values of the column:
numerically for integers and floats, chronologically for Date and Datetime, in
the order of the categories for Enum, and alphabetically for strings and
Categorical.
econometricsmodels.FEResults(raw)
FE estimation results.
Array-valued properties (params, std_errors, etc.) are exposed
as dictionaries keyed by coefficient name (for O(1) lookup of a
single parameter). Use coef_table() for a row-oriented listing.
fixed_effects() (the fixed effects themselves) is provided as a
separate method rather than a field on this class
(docs/spec/fe-spec.md section 3.5).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw
|
FEResult
|
The estimation result object returned by |
required |
Note
Users normally do not construct this directly; it is returned
by FE.fit().
aic
property
Akaike Information Criterion (AIC).
bic
property
Bayesian Information Criterion (BIC).
conf_int
property
Coefficient name to confidence interval (lower, upper).
cov_type
property
Standard error type actually used (normalized to lowercase).
dep_var_name
property
Column name of the dependent variable.
df_model
property
Model degrees of freedom (k, the number of slope
coefficients).
df_resid
property
Residual degrees of freedom (n - n_entities - k for
one-way, n - n_entities - n_periods + 1 - k for two-way).
dk_bandwidth_used
property
Driscoll-Kraay bandwidth actually used: the explicit
dk_bandwidth if given, otherwise the value chosen automatically,
floor(4 * (t / 100) ** (2 / 9)) where t is the number of
unique time periods in FEOptions.dk_time. None unless
cov_type="dk".
f_df_denom
property
Denominator degrees of freedom of f_statistic (None when it
is NaN). Follows cov_type like the t-tests (G - 1 for
cov_type="cluster", T - 1 for "dk", df_resid otherwise),
so it equals stat_df whenever f_statistic is not NaN. Use this
to recompute the p-value from f_statistic.
f_df_num
property
Numerator degrees of freedom of f_statistic (None when it
is NaN, i.e. there are no slope coefficients).
f_p_value
property
P-value of the F-statistic.
f_statistic
property
F-statistic for the joint significance of the slope
coefficients (classical F-test when cov_type="classical", a
robust Wald test otherwise).
log_likelihood
property
Log-likelihood.
n_entities
property
Number of panel entities.
n_obs
property
Number of observations.
n_periods
property
Number of unique time periods (two-way effects only; None
for one-way). Two-way requires a balanced panel, so this equals
the number of observations per entity.
p_values
property
Coefficient name to two-sided p-value.
param_names
property
List of coefficient names (no intercept: within-transformed variables have no constant term).
params
property
Coefficient name to coefficient value.
r_squared_between
property
Between R² (based on entity-mean variables).
r_squared_overall
property
Overall R² (based on the untransformed variables).
r_squared_within
property
Within R² (based on the within-transformed variables).
residuals
property
Within-transformed residuals (in observation order).
stat_df
property
Degrees of freedom of the t distribution behind test_stats,
or None when stat_dist is "normal". May differ from
df_resid (cluster-robust inference uses G - 1, Driscoll-Kraay
T - 1), so use this to recompute p-values from test_stats.
stat_dist
property
Distribution of test_stats: "t" (t-statistics) or
"normal" (z-statistics).
std_errors
property
Coefficient name to standard error.
test_stats
property
Coefficient name to test statistic (t-statistic; see
stat_dist).
coef_table()
Row-oriented summary table of the coefficients.
Shaped to be usable almost as-is in a REST API response (same
policy as OLSResults.coef_table()). Returned as list[dict]
rather than a polars DataFrame, per the project's policy of
not using DataFrames for the coefficient table itself.
Returns:
| Type | Description |
|---|---|
list[dict[str, float | str]]
|
A list of dictionaries, one per coefficient. Keys are |
list[dict[str, float | str]]
|
|
list[dict[str, float | str]]
|
|
fixed_effects()
The fixed effects themselves (α_i for entity, γ_t for
time), recovered post-hoc from the fitted coefficients.
One-way: dict[str, float] keyed by entity id. Two-way:
dict[str, dict[str, float]] with top-level keys "entity"/
"time". See docs/spec/fe-spec.md
section 3.5 and _lib.FEResult.fixed_effects's docstring for
the exact formula, including the two-way normalization
convention. α_i/γ_t are not individually identified in the
two-way case, so γ_t of the first period in time order (the
order of the values of the time column) is fixed to 0 and
α_i absorbs the overall level. The "time" dictionary lists
the periods in time order.
fixest::fixef() instead uses the first time value in
observation order as the reference, so the two match
numerically only when both choose the same reference period.
Returns:
| Type | Description |
|---|---|
dict[str, float] | dict[str, dict[str, float]]
|
The fixed effects, shaped as described above. |