oster_bounds
Assess whether unobserved confounders could overturn a treatment effect by computing Oster's bounding coefficient and breakdown delta from short and long regressions, then flag fragile results when delta falls below 1.
Instructions
Oster (2019) sensitivity to selection on unobservables -- computes the bounding coefficient under the assumption that selection on unobservables (proportional to delta x selection on observables) brings the explained variance to r_max. The breakdown delta tells you how strong unobserved selection has to be to overturn your result. Assumptions: Selection on unobservables is proportional (by factor delta) to selection on observables; r_max upper-bounds the explained variance achievable with all confounders included; Linear functional form for y on (treat, controls). Pre-conditions: you have fitted both a short (treatment-only) and long (treatment + controls) regression of y; long-regression R^2 is meaningfully larger than short-regression R^2. Failure modes: breakdown delta < 1.0 (weak unobservables overturn the result) -> The result is fragile; report the breakdown delta alongside the point estimate; r2_long ~ r2_short (controls add no explanatory power) -> Oster's identified set degenerates when long and short R^2 are nearly equal; use sp.evalue or sp.sensemakr instead. Alternatives: sp.evalue, sp.sensemakr, sp.rosenbaum_bounds. Typical minimum N: 200.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| y | No | Outcome (alternative to passing beta_short/long directly) | |
| alpha | No | Significance level for confidence intervals and tests. | |
| delta | No | Ratio of unobserved-to-observed selection (1.0 = equally strong) | |
| r_max | No | Hypothetical R^2 from a regression that includes all unobserved confounders; default 1.3*R^2_long | |
| treat | No | Treatment indicator or first-treatment-period column. | |
| detail | No | Payload depth: 'minimal' (~150 tokens) for sub-step calls where only the point estimate is needed; 'standard' (~1K tokens) for diagnostics + coefficient table; 'agent' (~2K tokens, default) adds violations / next_steps / suggested_functions so the LLM can plan its next call without another round-trip. | agent |
| r2_long | No | r2_long parameter (float). | |
| controls | No | Control-variable column names. | |
| r2_short | No | r2_short parameter (float). | |
| as_handle | No | If true, cache the fitted result on the server and return result_id + result_uri alongside the JSON payload so a subsequent tools/call can chain without re-running. | |
| beta_long | No | beta_long parameter (float). | |
| data_path | No | Absolute path or URL to a data file. Supported: .csv / .tsv / .txt (delimited), .parquet / .pq, .feather / .arrow, .xlsx / .xls, .dta (Stata), .json / .jsonl. Schemes: file://, s3://, gs://, https://. | |
| result_id | No | Optional handle to a previously-fitted result (returned by an earlier call when as_handle=true). Tools that operate on a fitted object accept this in place of re-supplying data_path + columns. | |
| beta_short | No | Short-regression coefficient; if None, fit from data | |
| data_columns | No | Optional column projection. Parquet/Feather/Stata loaders honour this for fast partial reads. | |
| data_sample_n | No | Optional uniform random subsample size (seed=0, deterministic) — useful on huge panels. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||