F2-smoke-01 — OLS slope with firm-clustered uncertainty
Question
Estimate the population linear-projection slope β in y = α + βx + ε for a synthetic panel of firms, with a standard error that allows observations from the same firm to share a common shock (independent across firms, dependent within firms). This is an association, not a causal effect.
Data and exclusions
data/panel.csv (SHA-256 968410b9…5ce5a8, key input_sha256) has 2000 rows (n_input_rows). Columns are firm_id, x, y. Nothing is missing or non-finite, and no rows are duplicated. There are 50 firms (n_clusters), each with exactly 40 observations (obs_per_cluster_min, obs_per_cluster_max). The two exclusion rules (missing values; non-finite values) removed 0 rows (out/exclusions.csv), so n_analysed = 2000. data_issues is empty.
Method
- Pooled OLS of y on x with an intercept.
- Baseline: the conventional homoskedastic, non-clustered SE (
se_ols). - Main inference: the cluster-robust sandwich SE by firm_id with the CR1 small-sample correction G/(G−1)·(n−1)/(n−k) (
se_cluster). The 95% CI is β̂ ± t₀.₉₇₅,G−1·se_cluster, with G−1 = 49 degrees of freedom (ci_df,t_crit_cluster= 2.0096). - The method uses no randomness (
random_seed= null). out/analysis.pyregenerates every number. I checked the clustered SE against an independent numpy sandwich computation, and the two agree to about 1e-17 (out/state/checks.md).
Results
- Slope:
beta_hat= 0.8051. - Intercept:
alpha_hat= 1.4440. - 95% cluster-robust CI for β: [
beta_ci_low,beta_ci_high] = [0.6581, 0.9521]. It excludes zero.
Uncertainty
- Clustered SE:
se_cluster= 0.0731. - Naïve OLS SE:
se_ols= 0.0241. - The clustered SE is about 3.0 times the naïve one (
se_ratio_cluster_over_ols= 3.03). - The naïve 95% CI [
baseline_ci_low_ols,baseline_ci_high_ols] = [0.7578, 0.8524] is therefore far too narrow.
This inflation is expected for two reasons found in the audit (out/state/data_audit.md): about 45% of the variance of x and 53% of the variance of the OLS residual lie between firms, and each firm has 40 observations.
Limitations and open issues
- Cluster-robust inference here relies on asymptotics in the number of firms. With G = 50 balanced clusters the CR1 + t(G−1) approach is generally adequate, but it is not exact. I did not run a wild-cluster bootstrap, because the task does not require it.
- β is a linear-projection coefficient. It is not a causal effect, and it is not a within-firm (fixed-effects) slope. Because x has a large firm-level component, a within-firm slope could differ.
- The data are synthetic. Feasibility is "complete".