Files
chendun1995andClaude Opus 5.5 5c4407f876 pvisim: parameters, simulator, claims records, tests; calibration of all worlds to Medicare targets
- latent-severity DGP with physicians (skill, style), policies A/B1/B2/sequential, common random numbers
- sharp null exact at the patient level (tested)
- 01_calibrate.R: joint logit-scale update; all worlds match early PVI 3.2%, late PVI 22.5/3.6%, CLTI 7.8%, death 35%
- W4 deferral target 15% (trial-like crossover); post-CLTI PVI lowered so late PVI is mostly elective

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-27 08:15:18 -04:00

52 lines
2.2 KiB
R

# Parameters: read the YAML, then apply a world and a truth scenario as overrides.
#' Recursively merge `override` into `base` (lists only; scalars replace).
deep_merge <- function(base, override) {
for (nm in names(override)) {
if (is.list(override[[nm]]) && is.list(base[[nm]])) {
base[[nm]] <- deep_merge(base[[nm]], override[[nm]])
} else {
base[[nm]] <- override[[nm]]
}
}
base
}
#' Path of the default parameter file, inside the installed or loaded package.
default_params_path <- function() {
p <- system.file("params", "dgp_default.yml", package = "pvisim")
if (p == "") stop("dgp_default.yml not found; load the package with pkgload::load_all('pvisim')")
p
}
#' Load parameters for one world and one truth scenario.
#'
#' @param world name in `worlds:` (W0, W1, W1_rho0, W2, W3, W4, W5, WR).
#' @param scenario name in `scenarios:` (null, harm, benefit_harm).
#' @param path YAML file; defaults to the package's dgp_default.yml.
#' @param overrides optional list merged last (used by calibration and tests).
#' @param calibrated apply the world's entry in `calibration_file` (intercepts solved by
#' simulations/01_calibrate.R under the null scenario), after the world and before the
#' scenario. Calibration itself runs with FALSE.
load_params <- function(world = "W0", scenario = "null", path = default_params_path(),
overrides = NULL, calibrated = TRUE,
calibration_file = "simulations/config/calibrated.yml") {
raw <- yaml::read_yaml(path)
if (!world %in% names(raw$worlds)) stop("unknown world: ", world)
if (!scenario %in% names(raw$scenarios)) stop("unknown scenario: ", scenario)
par <- raw[setdiff(names(raw), c("worlds", "scenarios"))]
par <- deep_merge(par, raw$worlds[[world]])
if (calibrated && file.exists(calibration_file)) {
cal <- yaml::read_yaml(calibration_file)[[world]]
if (!is.null(cal)) par <- deep_merge(par, cal)
par$calibrated <- !is.null(cal)
} else {
par$calibrated <- FALSE
}
par <- deep_merge(par, raw$scenarios[[scenario]])
if (!is.null(overrides)) par <- deep_merge(par, overrides)
par$world <- world
par$scenario <- scenario
par
}