Standard Errors in Panel Data

Which estimator gives you honest inference? A Python tutorial

1.03pooled OLS · double the truth
0.48fixed effects recover beta
6.6%FE + entity-clustered rejection

Carlos Mendez

Nagoya University (GSID)

June 11, 2026

The Tension

Act I

A t-statistic of 30 can be an illusion built on the wrong formula

You regress firm performance on R&D intensity and get a t-statistic of 30. Rock-solid?

In panel data, firm 1 in 2015 is not independent of firm 1 in 2016. Conventional standard errors assume it is — and the precision they report is fake.

With the same point estimate, six SE formulas tell six different stories

Eight model–SE combinations. The point estimate is fixed; only the bars (the standard errors) move.

Where we’re going

  • A simulated panel where we know the true effect (\(\beta = 0.5\))
  • Six SE estimators on the same biased pooled model
  • Fixed effects: the only thing that fixes the bias
  • A 500-run Monte Carlo: which SE actually controls size?

The Investigation

Act II

The lab: 100 firms × 10 years, with a known true effect of 0.5

  • Outcome \(y\) — firm performance (1,000 rows, 2010–2019)
  • Treatment \(x\) — R&D intensity, correlated with unobserved firm ability
  • Errors — within-firm AR(1) serial correlation, \(\rho = 0.5\)

Because ability drives both \(x\) and \(y\), pooled OLS is biased by design — and AR(1) errors make SE choice critical.

The true model bakes ability and serial correlation into the data

\[y_{it} = 2.0 + 0.5\,x_{it} + \mu_i + \lambda_t + \varepsilon_{it}\]

  • \(\mu_i\) — firm ability, correlated with \(x_{it}\) \(\Rightarrow\) omitted-variable bias
  • \(\lambda_t\) — weak year effects, \(\lambda_t \sim N(0, 0.5)\)
  • \(\varepsilon_{it}\) — AR(1) within firm, \(\rho = 0.5\) \(\Rightarrow\) within-cluster correlation

Persistent firm differences dominate — exactly what fixed effects absorb

10 sampled firms cluster in distinct regions (left); within-firm \(y\)\(x\) correlations center on 0.41 (right).

Pooled OLS reports 1.03 — more than double the true 0.5

Model / SE \(\hat\beta\) SE \(t\)
Pooled OLS (conventional) 1.0318 0.0345 29.9

The estimate is wrong, and the tiny SE makes us wrongly confident in the wrong number.

White SEs barely move the needle — correlation, not heteroskedasticity, is the problem

\[\hat{\Sigma}_{\text{White}} = (X'X)^{-1}\left(\sum_{i=1}^{N} X_i'\,\hat{e}_i^{\,2}\,X_i\right)(X'X)^{-1}\]

White SE = 0.0361 vs conventional 0.0345 — the \(t\) slips only from 29.9 to 28.6.

Clustering on firms inflates the SE by 80% — the honest correction

Model / SE \(\hat\beta\) SE \(t\)
Conventional 1.0318 0.0345 29.9
White (HC) 1.0318 0.0361 28.6
Cluster: entity 1.0318 0.0621 16.6

Ten observations from one firm carry far less than ten independent observations’ worth of information.

Time clustering looks precise but lies: only 10 clusters break the asymptotics

Model / SE \(\hat\beta\) SE \(t\)
Cluster: entity (100 groups) 1.0318 0.0621 16.6
Cluster: time (10 groups) 1.0318 0.0168 61.3
Cluster: both 1.0318 0.0532 19.4

Cluster on the dimension with \(\ge 40\)\(50\) groups. Here that is firms (100), not years (10).

Fixed effects subtract each firm’s average — and the bias vanishes

from linearmodels.panel import PanelOLS
mod_fe = PanelOLS.from_formula("y ~ 1 + x + EntityEffects",
                               data=df_panel)
res = mod_fe.fit(cov_type="clustered", cluster_entity=True)
print(res.params["x"])       # 0.4829  — recovers the true 0.5
print(res.std_errors["x"])   # 0.0357

Fixed effects recover 0.48 — the bias was the model, not the SE

0.48

Entity FE \(\hat\beta\) (true \(\beta = 0.5\)); SE 0.0357 · pooled OLS gave 1.03

One picture: no SE rescues a biased estimate; FE intervals cover the truth

95% CIs across all eight methods. Teal dashed line = true \(\beta = 0.5\). Pooled intervals (right) miss it; FE intervals (orange) cover it.

Driscoll-Kraay targets cross-sectional shocks — weak here, vital elsewhere

Model / SE \(\hat\beta\) SE \(t\)
Pooled (Driscoll-Kraay, BW=3) 1.0318 0.0158 65.4

Smallest SE in the deck — because firms are independent given their fixed effects in this DGP.

The Resolution

Act III

Only Monte Carlo proves it: FE + entity-clustered rejects at 6.6%, near the nominal 5%

Rejection rates over 500 simulations, six FE+SE combinations. Dashed line = nominal 5%.

The too-small SEs sit at 0.55–0.58× the honest benchmark — understating uncertainty by ~40%

SE ratios relative to the entity-clustered benchmark. Ratios below 1.0 understate uncertainty.

Does fixing the SE make the estimate causal? No

Objection. “Clustered/robust SEs and a 6.6% rejection rate mean my coefficient is now the true causal effect.”

Response. Standard errors fix inference, never identification. The 0.48 estimate is unbiased here only because fixed effects removed the time-invariant confounder \(\mu_i\). A time-varying confounder would still bias \(\beta\) — and no SE could detect it.

The decision rule: fix the model first, then cluster on the larger dimension

Fix the bias

  • Add fixed effects if there is entity-level heterogeneity
  • SEs address precision, never bias
  • Pooled \(1.03 \to\) FE \(0.48\)

Fix the inference

  • Cluster on the larger dimension (firms: 100, not years: 10)
  • Two-way clustering = safe default when both have \(\ge 40\)\(50\) groups
  • Driscoll-Kraay for long macro panels

Standard errors set the width of your conclusion — fixed effects set whether it is the right one.