# F2-smoke-01 — Slope of y on x with firm-clustered uncertainty ## Question Estimate the population slope β in the linear projection y = α + βx + ε using a synthetic firm panel (`data/panel.csv`), with standard errors that allow arbitrary correlation within a firm (a shared firm-level shock) while treating firms as independent of one another. ## Data and exclusions - Input: `data/panel.csv`, SHA-256 `968410b9…5ce5a8`, 2000 rows read (`n_input_rows`), columns firm_id, x, y. - No missing values, no duplicate rows. The panel is balanced: 50 firms with 40 observations each (`n_clusters` = 50). - No exclusions (`out/exclusions.csv`): `n_analysed` = 2000. No data issues were found (`data_issues` = []). - Information rule respected: only `data/panel.csv` is read. ## Method - OLS of y on x with an intercept, giving `beta_hat` and `alpha_hat`. - Naïve baseline: the conventional homoskedastic OLS standard error (`se_ols`), which assumes all observations are independent. - Main inference: a cluster-robust (CR1) sandwich variance clustered by firm_id. It uses the usual small-sample factor G/(G−1)·(N−1)/(N−K), the same one Stata and statsmodels use. This gives `se_cluster`. The 95% CI is beta_hat ± t₀.₉₇₅(G−1)·se_cluster, with critical value `ci_t_critical_df_Gminus1` (G−1 = 49 df). - The computation is deterministic and uses no randomness (`random_seed` = null). The script is `out/analysis.py`. ## Results - `beta_hat` = 0.8051; `alpha_hat` = 1.4440. - `se_ols` = 0.0241 (naïve); `se_cluster` = 0.0731. - 95% clustered CI for β: [`beta_ci_low`, `beta_ci_high`] = [0.658, 0.952]. - `feasibility` = "complete". ## Uncertainty - The clustered SE is about 3.0 times the naïve OLS SE (`se_ratio_cluster_over_ols` = 3.03). The naïve SE therefore seriously understates the sampling uncertainty when observations share a firm-level shock. For comparison, the naïve 95% CI would be [`baseline_ci_ols_low`, `baseline_ci_ols_high`] = [0.758, 0.852], which is much too narrow. - Even with the clustered interval, β is clearly positive: the CI excludes 0. - Cross-check: statsmodels' cluster-robust SE agrees with `se_cluster` to machine precision. Statsmodels' default interval uses a normal critical value ([0.662, 0.948]), so it is slightly narrower than the reported t(49) interval. ## Limitations and open issues - β is a linear-projection (associational) slope, not a causal effect. The data are synthetic. - Cluster-robust inference is asymptotic in the number of clusters. With 50 balanced clusters, CR1 with t(G−1) is generally adequate, but it is not exact. No wild-cluster bootstrap was run because the task does not require it. - The CI's coverage depends on firms being independent of each other. The data cannot be used to test that assumption.