Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Where Emergency Department Wait Time Actually Comes From

tests python licence: MIT

→ Open the interactive dashboard — national estimates with confidence intervals and NCHS reliability flags, the variation decomposition, and the peak-hour null result. No install.

A design-correct analysis of 16,025 real emergency department visits from the CDC/NCHS 2022 National Hospital Ambulatory Medical Care Survey, weighted to the 155,397,747 ED visits made in the United States that year.

The question this project set out to answer was the one ED operations folklore always asks: when is the department worst? The data gave a more useful answer — it isn't "when", it's "where" — and one number that reframes the whole capacity conversation.

between-hospital spread in median door-to-provider   2.4 → 75 min      (IQR 16 min)
between-hour     spread in median door-to-provider  11 → 22 min      (IQR 4.5 min)
                                                     ────────────────────────────
                                       between-hospital variation is 3.56× larger

Headline findings

Estimate 99% CI
National ED visits, 2022 155,397,747 matches CDC's published total exactly
Median door-to-provider 16 min 90th percentile: 98 min
Left without being seen (LWBS) 1.89% 1.12 – 2.66%
Admitted 11.46% 8.67 – 14.25%
Median boarding time (admitted) 62 min 90th pct 460 min, 99th pct 2,470 min
ED bay-hours lost to boarding 48.6 million / year the single largest recoverable capacity item

1. Which hospital you walk into matters ~4× more than what time you arrive. Across 45 EDs with ≥100 sampled visits, median door-to-provider ranges from 2 to 74 minutes. Across the 24 hours of the day it ranges from 11 to 22 minutes. The worst individual ED averages 139 minutes to provider with 6.2% LWBS; one runs 17.7% LWBS. Site-level operating practice, not the time on the clock, is where the variance is.

2. The peak-hour effect is real in direction and too small to act on — an honest null. Arrivals do surge 16:00–19:00 and waits are directionally worse (median 17 vs 13 min overnight; LWBS 2.18% vs 1.07%). But under design-based inference the difference does not clear significance at the α = 0.01 level CDC recommends for this file (wait p = 0.41, LWBS p = 0.082). A staffing case built on peak-hour degradation would not survive scrutiny. This is reported as a negative result rather than quietly dropped.

3. Boarding is the actual capacity crisis. An admitted patient holds a treatment bay for a median of 62 minutes after the decision to admit — but 460 minutes at the 90th percentile and 41 hours at the 99th. Nationally that is 48.6 million bay-hours a year of ED treatment capacity consumed by patients who have already been admitted and are waiting for an inpatient bed. No amount of ED-side staffing fixes a downstream bed problem.

4. Patients without coverage are the ones who give up and leave. LWBS runs 2.87% for self-pay and 2.45% for Medicaid/CHIP against 0.65% for Medicare — a 4.4× gap between self-pay and Medicare. Directionally unambiguous and consistent across every uninsured category, though the pairwise test lands at p = 0.014 and so does not clear the α = 0.01 bar either. Reported with that caveat attached.

5. Triage works, with one wrinkle. Mean wait climbs from 26.9 min (ESI 1 Immediate) to 40.5 min (ESI 4 Semi-urgent) as it should — then falls to 30.1 min for ESI 5 Nonurgent. That non-monotonicity is the signature of fast-track pathways pulling the simplest patients out of the main queue.

Which hospital you walk into matters more than what time you arrive

Arrival volume and the wait it produces

LWBS by expected payer


Why this is harder than it looks

NHAMCS is a stratified multi-stage probability sample, not a table of patients. Three things have to be right or every number above is wrong:

  1. Weighting. Each record carries PATWT, an inflation factor to national totals. Unweighted, the "national LWBS rate" is a statement about which hospitals CDC happened to sample. The pipeline validates its own weighting by reproducing CDC's published national total to the visit — if the byte offsets were wrong, that check fails and the build refuses to write.

  2. Variance. Visits from the same ED are correlated, so treating 16,025 rows as 16,025 independent observations understates standard errors badly. src/survey.py implements the ultimate-cluster (with-replacement) estimator over CSTRATM/CPSUM that CDC prescribes, with Taylor linearisation for ratios and means. This is the difference between "peak hours are worse" and "peak hours are not distinguishable from noise" — the naive calculation would have confidently reported the former.

  3. Sentinel codes. NHAMCS encodes missingness as negative numbers with different meanings: −9 blank, −8 unknown, −7 not applicable. Reading them as numbers is the classic way to publish an ED with a mean wait of minus four minutes. −7 on WAITTIME is kept as a distinct flag rather than dropped, because "never seen by a provider" is a finding, not a gap.

Estimates failing the NCHS presentation standard (n < 30 or RSE > 30%) are labelled unreliable everywhere they appear rather than silently printed.

The record layout is derived, not hardcoded

The public use file is 2,382 bytes of unlabelled ASCII per record. The byte offsets for its ~900 variables exist only inside CDC's 268-page documentation PDF, which is why most published analyses hardcode a handful of positions copied by hand.

src/nhamcs_layout.py parses the codebook out of the PDF and validates that the recovered fields tile the record, so the pipeline can be pointed at a different survey year. The 16 disposition flags — including LWBS — defeat text extraction because their columns are detached in the PDF, so they are transcribed explicitly and then structurally verified: the parser asserts ADMIT still sits at bytes 503–504 immediately after the block and that bytes 487–502 are claimed by nothing else. If CDC renumbers the file, that fails loudly instead of silently reading the wrong bytes as LWBS.


Stack

Python (pandas, NumPy, SciPy, Matplotlib) · SQL (SQLite star schema with CTEs, window functions, FILTER aggregates) · pypdf for codebook extraction · Parquet interchange.

SQLite is deliberate: the entire warehouse is one file a reviewer opens with no install, and it still supports every SQL construct the KPI layer needs.

Dimensional model

Grain: one row per ED visit. Conformed dimensions for hour-of-day, triage acuity, expected payer, disposition, and hospital.

The survey design columns live on the fact table, not behind a join — they describe how a row was sampled, not what it describes, and every correct aggregate must carry them. Hiding them behind a join makes it easy to write a query that silently drops the weighting and returns unweighted counts that look plausible and are wrong by four orders of magnitude.

python src/warehouse.py --list                    # available KPI queries
python src/warehouse.py --query hospital_variation

Reproducing

pip install -r requirements.txt
python src/download.py        # fetch the PUF + documentation from CDC (~40 MB)
python src/build_dataset.py   # parse fixed-width -> validated tidy parquet
python src/warehouse.py       # build the SQLite star schema, run the KPI suite
python src/analyze.py         # design-based estimates, figures, metrics.json

Or python run.py for the whole chain. Everything is deterministic; there is no sampling step and no seed to worry about.

On the raw data

The CDC survey file is not committed to this repository. It is a 38 MB third-party dataset governed by NCHS data use terms, and vendoring other people's data into a git history is poor practice regardless. src/download.py fetches it on demand and verifies the byte count.

NCHS terms permit statistical reporting and analysis, prohibit any attempt to identify a person or establishment, and prohibit linkage to individually identifiable data from other sources. This project does aggregate throughput analysis only and links to nothing.


What I would do with more of it

  • Model LWBS directly rather than slicing it — a survey-weighted logistic regression would separate the payer effect from the hospital effect, which the marginal tables here cannot.
  • Multi-year panel. 2022 still carries pandemic distortion; the 2019–2023 files share a layout and the parser already generalises across years.
  • Join CMS Hospital Care Compare (measures OP-18 and OP-22) to attach facility characteristics to the hospital-level spread and ask why the worst EDs are the worst. Note this would be a facility-level join only — NCHS terms forbid record-level linkage.

Data source

CDC/NCHS, National Hospital Ambulatory Medical Care Survey, 2022 Emergency Department Public Use File. Data: ftp.cdc.gov/pub/Health_Statistics/NCHS/Datasets/NHAMCS/ed2022.zip · Documentation: doc22-ed-508.pdf

Analysis and interpretation are mine and are not endorsed by CDC or NCHS.

About

Design-correct analysis of 16,025 real CDC emergency department visits: where ED wait time actually comes from. Survey-weighted estimation, ultimate-cluster variance, SQLite star schema.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages