{"id":51714499,"url":"https://github.com/rlarson94170/nsqip_cusum","last_synced_at":"2026-07-17T01:06:34.742Z","repository":{"id":338518671,"uuid":"1158129728","full_name":"rlarson94170/nsqip_cusum","owner":"rlarson94170","description":null,"archived":false,"fork":false,"pushed_at":"2026-02-27T00:52:17.000Z","size":60,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-27T07:49:42.099Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rlarson94170.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-14T21:02:35.000Z","updated_at":"2026-02-27T00:52:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/rlarson94170/nsqip_cusum","commit_stats":null,"previous_names":["rlarson94170/nsqip_cusum"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rlarson94170/nsqip_cusum","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rlarson94170%2Fnsqip_cusum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rlarson94170%2Fnsqip_cusum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rlarson94170%2Fnsqip_cusum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rlarson94170%2Fnsqip_cusum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rlarson94170","download_url":"https://codeload.github.com/rlarson94170/nsqip_cusum/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rlarson94170%2Fnsqip_cusum/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35563118,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-16T02:00:06.687Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-17T01:06:34.138Z","updated_at":"2026-07-17T01:06:34.733Z","avatar_url":"https://github.com/rlarson94170.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NSQIP CUSUM Surgical Outcome Monitoring\n\nBernoulli CUSUM charts for near-real-time monitoring of surgical complications\nusing NSQIP Case Details Report data, benchmarked against risk-adjusted site\nSAR expected rates or national observed rates. Generates comprehensive PDF\nreports and presentation slide decks for specialty and division-level quality\nimprovement review.\n\n## Quick Start\n\n1. **Open** `nsqip_cusum.Rproj` in RStudio\n2. **Install** required packages (see below)\n3. **Place files** in the `data/` folder:\n   - `Case_Details_Report.xlsx` — your latest NSQIP case download *(required)*\n   - `SAR_Site_Summary.xlsx` — your site SAR/ISAR summary *(recommended)*\n   - `surgeon_division_mapping.csv` — surgeon-to-division mapping *(for division reports)*\n4. **Run** `source(\"render_reports.R\")`\n5. **Find** PDFs in the `output/` folder\n\n## Project Structure\n\n```\nnsqip_cusum/\n├── nsqip_cusum.Rproj          # RStudio project file\n├── render_reports.R            # Master script — run this to generate all PDFs\n├── nsqip_cusum_report.qmd     # Quarto report template (parameterized)\n├── R/\n│   ├── benchmarks.R            # SAR rates: national + site risk-adjusted\n│   ├── data_processing.R       # Case Details ingestion, PATOS, divisions\n│   ├── cusum_functions.R       # CUSUM computation, charts, O/E trends\n│   └── render_beamer_slides.R  # Direct R → LaTeX slide deck generator\n├── data/                       # Your data files go here (not tracked by git)\n│   ├── Case_Details_Report.xlsx\n│   ├── SAR_Site_Summary.xlsx\n│   └── surgeon_division_mapping.csv\n├── output/                     # Generated PDFs and slide decks\n└── README.md\n```\n\n## Required R Packages\n\n```r\ninstall.packages(c(\n  \"quarto\", \"readxl\", \"dplyr\", \"tidyr\", \"lubridate\",\n  \"ggplot2\", \"scales\", \"knitr\", \"kableExtra\", \"tibble\", \"tinytex\"\n))\n```\n\nAlso needed: **Quarto** (bundled with RStudio ≥ 2022.07) and a **LaTeX**\ndistribution (`quarto install tinytex`).\n\n\n## Configuration\n\nAll settings are in the top section of `render_reports.R`:\n\n| Setting | Default | Description |\n|---------|---------|-------------|\n| `data_file` | `\"data/Case_Details_Report.xlsx\"` | Path to NSQIP Case Details download |\n| `site_sar_file` | `\"data/SAR_Site_Summary.xlsx\"` | Site SAR/ISAR summary (set `NULL` to skip) |\n| `surgeon_mapping_file` | `\"data/surgeon_division_mapping.csv\"` | Surgeon-to-division CSV (set `\"\"` to skip) |\n| `benchmark_type` | `\"site_expected\"` | `\"site_expected\"` (risk-adjusted) or `\"national_observed\"` |\n| `specialties` | General Surgery, Vascular, Thoracic, Plastics | Which specialties to report on |\n| `division_specialties` | General Surgery | Which specialties get division-level breakouts |\n| `min_division_cases` | `10` | Minimum cases required to generate a division report |\n| `odds_ratio` | `2.0` | Detection target: p₁ = OR × p₀ |\n| `target_arl` | `500` | Average run length before false alarm |\n| `render_slides` | `TRUE` | Also produce beamer slide decks |\n\n\n## Output\n\nA single `source(\"render_reports.R\")` call generates:\n\n**For each specialty** (e.g., General Surgery, Vascular, Thoracic, Plastics):\n- `NSQIP_CUSUM_{specialty}_{date}.pdf` — full PDF report\n- `NSQIP_CUSUM_{specialty}_{date}_slides.pdf` — beamer slide deck\n\n**For each division** within specialties listed in `division_specialties`:\n- `NSQIP_CUSUM_{specialty}_{division}_{date}.pdf` — division PDF report\n- `NSQIP_CUSUM_{specialty}_{division}_{date}_slides.pdf` — division slide deck\n\nDivisions are auto-discovered from the surgeon mapping file. Only divisions\nmeeting the `min_division_cases` threshold are rendered.\n\n\n## Benchmark Options\n\n| Mode | `benchmark_type` | p₀ source | Risk-adjusted? |\n|------|-----------------|-----------|----------------|\n| **Preferred** | `\"site_expected\"` | Site SAR expected rate | Yes — accounts for your case mix |\n| Fallback | `\"national_observed\"` | National SAR observed rate | No — raw specialty rates |\n\nWhen using `site_expected`, the system reads your `SAR_Site_Summary.xlsx` to\nextract the expected rate from the hierarchical model for each\nspecialty-complication pair. If a site rate is not available for a particular\ncomplication, the national observed rate is used as fallback. The system\nauto-detects SAR vs. ISAR format.\n\n\n## PDF Report Contents\n\nEach specialty/division PDF includes the following sections:\n\n### SAR Context\nPrior SAR results table with O/E ratios, percentiles, and assessments\n(Exemplary / As Expected / Needs Improvement). Color-coded rows highlight\nareas of concern.\n\n### Observed Rates vs. Benchmarks\nCurrent-period observed complication rates compared to benchmarks, with\nobserved/benchmark ratio for each complication.\n\n### Monthly Complication Dashboard\nEvent counts by month in a grid layout, organized by complication category\n(Infection, Respiratory, Renal, Cardiac, VTE/PE, Readm/ROR). Includes\ngranular sub-complications (e.g., Superficial/Deep/Organ-Space SSI, Renal\nInsufficiency vs. Dialysis) with PATOS exclusions applied. Shows raw rates\nand SAR benchmark rates for comparison.\n\n### CUSUM Charts\nOne chart per monitored complication, with:\n- Chart title colored by SAR assessment (red = Needs Improvement)\n- Subtitle showing p₀, p₁, observed rate, benchmark source\n- SAR O/E ratio and percentile annotation\n- Decision boundary (h), signal markers (▲), event ticks (|)\n\n### O/E Trend Charts\nHistorical O/E ratios across SAR periods for complications flagged as\nNeeds Improvement or with high outlier history. Red dots indicate periods\nflagged as high outlier. Division reports note that O/E trends reflect the\nspecialty-level SAR model.\n\n### Appendix: Procedure Mix Profile\nCase distribution by procedure category (using NSQIP targeted module flags\nand CPT code groupings), with complication rates and median length of stay\nper category.\n\n### Appendix: Targeted SAR Benchmarks\nFor specialties with targeted procedure data (e.g., Colectomy, Proctectomy,\nPancreatectomy, Hepatectomy, VHR), shows site-level SAR results alongside\ndivision-level unadjusted observed rates for direct comparison. Includes\nprocedure-specific complications like anastomotic leak and prolonged NPO/NGT.\n\n### Appendix: Complication Case List\nPatient-level detail for the most recent quarter's complications, including\ncase ID, surgeon, CPT, ASA class, length of stay, and specific occurrences.\nExcludes PATOS complications. Readmission entries indicate whether the\nreadmission was related to the index procedure.\n\n### Appendix: Case Mix\nASA class distribution and monthly case volume chart.\n\n\n## Slide Decks\n\nSlide decks are generated directly from R as LaTeX beamer documents (not via\nQuarto) to avoid pandoc's beamer frame-management limitations. Each deck\nincludes:\n\n- Title slide with specialty/division, date range, and case count\n- Report summary with key parameters\n- Monthly case volume chart\n- Prior SAR performance table\n- Observed vs. benchmark comparison table\n- Monthly complication dashboard\n- CUSUM charts (one per slide)\n- O/E trend charts for flagged complications\n- Procedure mix profile\n- Targeted SAR benchmark tables (when available)\n\nSlides use a 16:9 aspect ratio with institutional color theming (VCU blue/gold).\nSet `render_slides \u003c- FALSE` in `render_reports.R` to skip slide generation.\n\n\n## Surgeon-to-Division Mapping\n\nThe mapping file (`surgeon_division_mapping.csv`) links individual surgeons\nto their division for division-level reporting. Format:\n\n```csv\nsurgeon_name,specialty,division\n\"LastName, FirstName\",General Surgery,Surgical Oncology\n\"LastName, FirstName\",General Surgery,Colorectal\n```\n\nThe `surgeon_name` column should match the surgeon name format in the NSQIP\nCase Details Report. The system uses this to filter cases by division and\ngenerate separate reports for each division within a specialty.\n\n\n## Updating for New Data\n\n### New Case Details download:\n1. Place the new `.xlsx` in `data/`\n2. Update `data_file` path in `render_reports.R`\n3. Run `source(\"render_reports.R\")`\n\n### New SAR/ISAR release:\n1. Place the new site summary in `data/`\n2. Update `site_sar_file` path in `render_reports.R`\n3. Update national rates in `R/benchmarks.R` from the new SAR Summary Report\n4. Re-render\n\n### New surgeons or division changes:\n1. Update `surgeon_division_mapping.csv`\n2. Re-render — divisions are auto-discovered from the mapping\n\n\n## Methodology\n\n### Bernoulli CUSUM\n\nFor each case in chronological order:\n\n- **Score:** s = log[p₁(1-p₀) / (p₀(1-p₁))] if event; log[(1-p₁)/(1-p₀)] if not\n- **Accumulation:** C_i = max(0, C_{i-1} + s_i)\n- **Signal:** When C_i ≥ h\n- **Reset:** CUSUM resets to 0 after each signal\n\n### Parameters\n\n| Parameter | Default | Description |\n|-----------|---------|-------------|\n| p₀ | Site expected rate | Acceptable complication rate |\n| p₁ | OR = 2× vs p₀ | Rate to detect |\n| h | Auto (ARL₀≈500) | Decision boundary via Monte Carlo calibration |\n\nThe decision boundary h is calibrated so that, when the true rate equals p₀,\na false alarm occurs on average once every ~500 cases.\n\n### PATOS Exclusions\n\nPer SAR methodology, complications Present at Time of Surgery are excluded\nfrom event counts for: Pneumonia, Ventilator \u003e48h, UTI, SSI (all types),\nand Sepsis. This aligns the raw case data with how the SAR calculates its\nbenchmark rates.\n\n### Composite Outcomes\n\n| Outcome | Components |\n|---------|-----------|\n| Morbidity | SSI + wound disruption + pneumonia + unplanned intubation + vent \u003e48h + dialysis + renal insufficiency + UTI + stroke/CVA + cardiac arrest + MI + sepsis |\n| Cardiac | Cardiac arrest + MI |\n| VTE | PE + venous thrombosis requiring therapy |\n| Renal Failure | Renal insufficiency + postop dialysis |\n| SSI | Superficial + deep incisional + organ/space |\n\n### Division-Level Benchmarking\n\nDivision reports use the **specialty-level** SAR expected rates as p₀ (since\nNSQIP does not produce division-level risk-adjusted models). Targeted SAR\ntables display site-level risk-adjusted benchmarks alongside division-level\nunadjusted observed rates, clearly labeled to support meaningful comparison.\n\n\n## Customization\n\n### Change detection sensitivity\n- `odds_ratio` (default 2.0): Lower → more sensitive; Higher → fewer false alarms\n- `target_arl` (default 500): Lower → quicker detection but more false alarms\n\n### Add specialties\nAdd to the `specialties` vector in `render_reports.R` and add corresponding\nnational rates in `R/benchmarks.R`. Site SAR rates are auto-parsed.\n\n### Add division breakouts for another specialty\nAdd the specialty name to `division_specialties` in `render_reports.R` and\nensure the surgeon mapping CSV includes entries for that specialty.\n\n### Skip slide generation\nSet `render_slides \u003c- FALSE` in `render_reports.R`.\n\n\n## Limitations\n\n- **Benchmark timing:** SAR rates reflect a prior period; case mix may shift\n- **No dynamic risk adjustment:** The CUSUM monitors raw event streams; only\n  the p₀ benchmark incorporates risk adjustment\n- **Division benchmarks:** Division reports use specialty-level SAR expected\n  rates since division-level risk models are not available from NSQIP\n- **NSQIP sampling:** Not all surgical cases are captured\n- **Intended for internal QI** — not a substitute for official SAR profiling\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frlarson94170%2Fnsqip_cusum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frlarson94170%2Fnsqip_cusum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frlarson94170%2Fnsqip_cusum/lists"}