readmit creates editable, user-owned Readmission Risk Pool (RRP)
projects. Each project includes configuration, source-mapping and
risk-provider scripts, branding, and its own Shiny application.
Persistent history can be initialized explicitly, rrp_run() retains
completed assessments, and status and history inspection are available.
rrp_refresh_products() writes analytical CSVs from retained history. The
project app displays an interactive Current Risk Pool, a selected episode's
recorded risk trajectory, and a snapshot-level Overview.
After installing readmit, create a project at a new destination:
library(readmit)
project <- rrp_project_init(
path = "my-rrp-project",
project_id = "my-project"
)
rrp_project_validate(project)
The path is relative to your current working directory unless you supply
an absolute path. Its parent directory must already exist, and the
destination must not exist, even as an empty directory. The generated
files belong to you: edit rrp-project.dcf, rrp-authoring.dcf,
_brand.yml, R/produce-canonical.R, and R/calculate-risk.R for your
project. rrp_project_validate() checks that the configuration and both
authoring functions load; it does not run them. Both generated functions
begin as deliberate stubs, so the untouched project passes this
structural check. Implement the source mapper to return the canonical
discharge episodes and terminal events described in the project README,
and implement the risk provider for eligible episodes. Validate again
after editing. Validation checks that the scripts load; it does not
establish that their data or predictions will work during a run.
Then initialize persistent history and run at an explicit UTC analytical time:
rrp_state_init(project)
assessment <- rrp_run(
project, as.POSIXct("2026-01-10 12:00:00", tz = "UTC")
)
rrp_project_status(project)
rrp_inspect_history(project, run_id = assessment$run_id)
rrp_refresh_products(project)
This creates empty state/history.duckdb tables in the project and
refuses to overwrite existing state. State initialization does not run
either authoring function. Each rrp_run() call obtains canonical
facts, assesses eligible episodes through the provider, and atomically
appends the completed run and its episode outcomes. It returns the run
ID and accepted, failed, and ineligible counts. rrp_project_status()
also works before state initialization; rrp_inspect_history() requires
state. Both read retained information without sourcing your scripts. A
provider failure is retained for its episode while other eligible
episodes continue. Completed runs append history; later event knowledge
does not rewrite earlier results. After at least one completed run,
rrp_refresh_products() reads history and writes
state/products/current-remaining-risk.csv,
remaining-risk-trajectory.csv, and operational-scope-summary.csv. It
selects the run with the greatest analytical time, which may differ from
the most recently executed run. Supply the complete relevant discharge
population for operational assessments: a later partial run replaces the
earlier population in current products. The package determines clinical
eligibility. Eligible provider-failure episodes stay in the current-risk
file with a missing probability; earlier estimates are not substituted.
The trajectory contains recorded accepted estimates for current eligible
episodes. Read the generated files with ordinary CSV tools, such as
read.csv(file.path(project, "state/products/current-remaining-risk.csv")).
Refresh does not rerun your scripts, change history, or edit the app.
The three-file replacement is staged but is not fully atomic if a
filesystem error occurs during final replacement.
The application uses shiny, bslib, reactable, plotly, and yaml in the environment
where it runs. Install them there, then launch the app directly from the
same working directory used in the example:
install.packages(c("shiny", "bslib", "reactable", "plotly", "yaml"))
shiny::runApp("my-rrp-project/app")
The app opens with Current Risk Pool and Overview navigation. Before products exist, it shows a clear empty state. After refresh, Current Risk Pool displays accepted and failed eligible episodes with search, sorting, numeric-range filtering, and row selection. Failed predictions remain visible under numeric filtering and show Unavailable rather than zero risk. Selecting an episode shows its current estimate separately from accepted historical assessments in an interactive point chart and exact-observation table; compact sparklines appear in the pool. Overview summarizes operational counts and the minimum, median, and maximum of accepted current estimates, independent of pool filters. The app's Reload Data control rereads existing CSVs; it does not generate products.