- 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]>
52 lines
2.2 KiB
R
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
|
|
}
|