Skip to content

About

Facetwork domain: reproducible US state x year data panel (Census ACS/PEP + BLS) — analysis spine for socioeconomics, migration, health over time

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

21 Commits

Folders and files

Repository files navigation

fwh_uspanel

A Facetwork domain that builds a reproducible US state × year data panel — the tidy, inspectable spine for a "what moves with what across US states over time" analysis (economics, migration, and — in v2 — health).

BuildPanel fetches three clean public sources, outer-joins them on (state, year), and caches one tidy table as CSV + JSON with a per-column coverage report. No charts or models yet — this is the dataset you look at before deciding the analysis.

FFL at a glance

The domain is driven from FFL, Facetwork's workflow language. A step is name = Facet(args); ordering comes from references, not line order — here a when gate runs the analysis only once the panel reports enough rows:

namespace my.uspanel {

    use uspanel.data

    /** Build the panel, then the findings page — only if the panel is complete. */
    workflow OrderedPanelRun(force: Boolean = false, min_rows: Int = 500) => (status: String, html_path: String) andThen {

        panel = uspanel.data.BuildPanel(force = $.force) andThen when {
            case $.n_rows >= $$.min_rows => {
                findings = uspanel.data.BuildFindings(force = $$.force)
                yield OrderedPanelRun(status = "completed", html_path = findings.html_path)
            }
            case _ => {
                yield OrderedPanelRun(status = "panel_too_thin", html_path = "")
            }
        }
    }
}
fw ffl run --primary my.ffl --library src/uspanel/ffl/uspanel.ffl \
  --workflow my.uspanel.OrderedPanelRun

📖 docs/ffl-examples.md — the full example gallery: the two-stage ingest/analysis split, why line order is not run order, call-time mixins (timeout/retry), catch for a missing CENSUS_API_KEY, wrapping the shipped workflows, and publishing the findings page. Every snippet there is compile-checked.

Feature specifications

Per-feature specs live in docs/ — how each feature works, what it fetches, its facets/workflows, and its cache/output:

Spec What it covers
Panel Build Flagship. BuildPanel: eight sources -> outer-join on (state, year) -> tidy CSV/JSON + coverage report.
Findings Analysis BuildFindings: within-state fixed-effects vs levels, state-clustered bootstrap, findings HTML page.
Data Sources The eight public feeds (ACS, BLS, PEP, NCHS, AIDSVu HIV, CDC COVID, county elections, SEC DERA) — endpoints, coverage, quirks.
Storage & Cache Backend-aware paths (local vs MinIO/S3), the BLS + DERA per-source caches.
Domain & Handlers facetwork.domains registration, dispatch wiring, task-list routing.

Index: docs/README.md.

v1 columns + sources (all verified clean-API)

column source coverage
population, median_hh_income, foreign_born_pct Census ACS 1-year (B01003/B19013/B05002) 2005–2023 (no 2020 1-yr release)
unemployment_rate BLS LAUS statewide, SA, annual mean (LASST<fips>…03) 2005–2024
net_domestic_migration, net_international_migration Census PEP components (vintage 2019) 2010–2019
mortality_all, cancer_death_rate, heart_death_rate, flu_pneumonia_death_rate, diabetes_death_rate, stroke_death_rate NCHS Leading Causes of Death by state (Socrata bi63-dtpu), age-adjusted per 100k 1999–2017

→ 1,326 rows (50 states + DC × 1999–2024), a deliberately ragged panel (columns span different years — downstream analysis must handle the gaps). The analyzable overlap where economics + migration + health + demographics all coexist is 2010–2017 (408 rows).

The data checks out: 2019's biggest domestic-migration losers are CA/NY/IL/NJ/MA (high-cost states), the gainers FL/TX/AZ/NC/SC (Sun Belt); and WV/MS (poorest states) top the all-cause, cancer, and heart-disease death rates while HI/CA sit lowest — the known health-disparity pattern.

Honest scope

  • Census now requires CENSUS_API_KEY for ACS/PEP query endpoints. BLS is keyless.
  • PEP migration is clean-API only for 2010–2019. 2020–2024 (bulk state-components CSV) and 2000–2009 (intercensal) are a documented fast-follow.
  • Health columns (v2, added) — NCHS age-adjusted death rates by state, 1999–2017 (cancer, heart, influenza/pneumonia, diabetes, stroke, all-cause). Still open: HIV (AIDSVu's republication of CDC surveillance, 2008+; CDC's AtlasPlus backend was withdrawn 2026-08-25) and COVID (CDC's by-state Socrata was retired; 2020+ is off the 2010–2017 analyzable window anyway) — both targeted fast-follows.
  • Country-level → state-level panel is deliberate: analyzing the US as one 50-year time series is a spurious-trend trap; 50 states × years with state/year fixed effects is where inference becomes real.

Workflow

uspanel.workflows.BuildUSStatePanel
  └─ uspanel.data.BuildPanel   # fetch ACS + BLS + PEP → join → CSV/JSON + coverage

Output → cache/uspanel/output/us_state_panel.{csv,json} (MinIO on the fleet).

Run

pip install -e .                       # requests only
export CENSUS_API_KEY=…                 # ACS/PEP; BLS needs no key
python -m pytest tests/ -q             # offline (sources mocked)

About

Facetwork domain: reproducible US state x year data panel (Census ACS/PEP + BLS) — analysis spine for socioeconomics, migration, health over time

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages