130 lines
6.5 KiB
YAML
130 lines
6.5 KiB
YAML
# Every number that defines the simulated world. Analysis plan v1.0, section 5.
|
|
# Time unit: month. Hazards are monthly, on the logit scale.
|
|
# Starting values are placeholders, to be tuned by calibration
|
|
# (simulations/01_calibrate.R, targets in plan section 5.4).
|
|
# Physician traits (skill k, style s) and patient frailty F are standard normal;
|
|
# their influence is set by the coefficients that multiply them.
|
|
|
|
size:
|
|
n_patients: 50000
|
|
n_physicians: 1500
|
|
panel_sdlog: 1.0 # lognormal panel weights; median panel about 20 at n = 50,000
|
|
months: 60 # follow-up months 0-59
|
|
window: 6 # strategy A: PVI in months 0-5
|
|
|
|
physician:
|
|
rho_skill_style: -0.3 # corr(k, s). Has no effect unless skill matters (world W1)
|
|
obl_intercept: 0.0 # logit P(office-based lab / ASC); about 50% of physicians
|
|
obl_style: 0.8 # high-style physicians more often work in OBL/ASC
|
|
|
|
patient:
|
|
age_min: 66
|
|
age_shape: 2.5 # age = 66 + Gamma(shape, scale); mean about 76
|
|
age_scale: 4.0
|
|
p_female: 0.50
|
|
p_black: 0.10
|
|
# comorbidities: logit P = qlogis(prev) + age_coef * (age - 76) / 10 + frailty_coef * F
|
|
comorbidity:
|
|
diabetes: {prev: 0.40, age_coef: -0.10, frailty_coef: 0.4}
|
|
ckd: {prev: 0.20, age_coef: 0.30, frailty_coef: 0.5}
|
|
chf: {prev: 0.20, age_coef: 0.40, frailty_coef: 0.6}
|
|
copd: {prev: 0.25, age_coef: 0.10, frailty_coef: 0.4}
|
|
prior_cvd: {prev: 0.45, age_coef: 0.20, frailty_coef: 0.3}
|
|
smoking: {prev: 0.25, age_coef: -0.40}
|
|
year_min: 2015
|
|
year_max: 2019
|
|
|
|
severity: # latent Z_t: walking limitation / ABI on a standard scale
|
|
z0_diabetes: 0.3
|
|
z0_smoking: 0.3
|
|
z0_ckd: 0.2
|
|
z0_sd: 1.0
|
|
r0: 0.02 # mean drift per month
|
|
r_diabetes: 0.01
|
|
r_smoking: 0.01
|
|
r_sd: 0.01 # patient-specific progression rate
|
|
eps_sd: 0.05 # month-to-month noise
|
|
|
|
treatment:
|
|
window: # elective PVI hazard, months 0-5, among the eligible
|
|
intercept: -5.4
|
|
z: 0.9 # confounding by indication
|
|
frailty: -0.3 # frail patients are less often offered PVI
|
|
age10: -0.3
|
|
diabetes: 0.1
|
|
ckd: -0.1
|
|
smoking: 0.1
|
|
style: 0.5 # physician style; world W2 sets it to the strong level
|
|
obl: 0.3
|
|
year: 0.05 # per calendar year after year_min
|
|
deferred: # elective PVI hazard from month 6 on (deferral / crossover)
|
|
intercept: -7.2
|
|
z: 0.0 # world W4 makes deferral severity-driven
|
|
style: 0.5
|
|
obl: 0.3
|
|
|
|
effect: # what a PVI does. Set by the truth scenario
|
|
relief: 0.0 # immediate drop in Z at PVI
|
|
kappa: 0.0 # extra Z drift per month after PVI
|
|
skill_kappa: 0.0 # kappa * exp(-skill_kappa * k): skill slows post-PVI progression
|
|
|
|
outcomes:
|
|
death: {intercept: -5.0, age10: 0.7, chf: 0.4, ckd: 0.4, copd: 0.3, frailty: 0.4, z: 0.1, clti: 0.8}
|
|
clti: {intercept: -6.6, z: 0.6, diabetes: 0.4, ckd: 0.3, smoking: 0.3, frailty: 0.2}
|
|
clti_false_code: {intercept: -9.0, style: 0.0} # factor 3 sets style
|
|
amputation: {intercept: -8.5, clti: 3.0, diabetes: 0.4, ckd: 0.4, z: 0.2}
|
|
bypass: {intercept: -7.8, z: 0.5}
|
|
repeat_revasc: {intercept: -5.3, skill: 0.0, style: 0.0, z: 0.2} # only after the index PVI
|
|
clti_revasc: {intercept: -4.5} # PVI after CLTI (not elective); most CLTI patients get bypass, tibial work, amputation or nothing
|
|
|
|
negative_controls: # never depend on PVI
|
|
nco1: {intercept: -6.75, frailty: 0.5, smoking: 0.4, age10: 0.3, z: 0.3} # hip fracture / pneumonia; z = PVI-free severity (D53)
|
|
nco2: {intercept: -7.1, style: 0.8, venous: 0.5} # varicose-vein ablation
|
|
nce: {intercept: -5.7, style: 0.8, frailty: -0.2} # low-value procedure, months 0-5
|
|
|
|
measurement: # what the analyst sees. World W5 switches to claims proxies
|
|
severity: exact # exact: analyst sees Z_t. proxy: only visit/testing counts. noisy: Z_t + error (EHR/registry)
|
|
noise_sd: 0.75 # noisy: SD of the monthly measurement error; Z_t has SD about 1 at diagnosis, so cor(observed, true) is about 0.8
|
|
proxy_intercept: -1.0 # monthly count ~ Poisson(exp(proxy_intercept + proxy_z * Z_t))
|
|
proxy_z: 0.5
|
|
proxy_window: 3 # observed severity = log1p(sum of counts over the last 3 months)
|
|
frailty_reliability: 1.0 # frailty index = sqrt(rel) * F + sqrt(1 - rel) * noise
|
|
smoking: true # true: analyst sees true smoking. coded: sensitivity / specificity below
|
|
smoking_sens: 0.6
|
|
smoking_spec: 0.98
|
|
|
|
worlds: # one factor at a time (plan section 5.2, D24). Overrides on the default.
|
|
# Intercepts are then re-solved per world by calibration, so every world
|
|
# matches the same Medicare targets unless `calibration_targets` says otherwise.
|
|
W0: {}
|
|
W1:
|
|
effect: {skill_kappa: 0.5}
|
|
outcomes: {repeat_revasc: {skill: -0.6}}
|
|
W1_rho0:
|
|
physician: {rho_skill_style: 0.0}
|
|
effect: {skill_kappa: 0.5}
|
|
outcomes: {repeat_revasc: {skill: -0.6}}
|
|
W2:
|
|
treatment: {window: {style: 1.6}, deferred: {style: 1.6}}
|
|
W3:
|
|
treatment: {window: {style: 1.6}, deferred: {style: 1.6}}
|
|
outcomes: {clti_false_code: {style: 0.8}, repeat_revasc: {style: 0.6}}
|
|
W4: # deferral common (as in trial conservative arms) and severity-driven
|
|
treatment: {deferred: {z: 0.8}}
|
|
calibration_targets: {late_not: 0.15}
|
|
W5:
|
|
measurement: {severity: proxy, frailty_reliability: 0.4, smoking: coded}
|
|
WE: # EHR/registry-like: severity recorded (ABI, symptom class) but with error (D55)
|
|
measurement: {severity: noisy, frailty_reliability: 0.7, smoking: true}
|
|
WR:
|
|
effect: {skill_kappa: 0.5}
|
|
treatment: {window: {style: 1.6}, deferred: {style: 1.6, z: 0.8}} # deferral at the Sorber rate, but severity-driven
|
|
outcomes: {repeat_revasc: {skill: -0.6, style: 0.6}, clti_false_code: {style: 0.8}}
|
|
measurement: {severity: proxy, frailty_reliability: 0.4, smoking: coded}
|
|
|
|
scenarios: # truth scenarios (plan section 5.3, D34)
|
|
"null": {effect: {relief: 0.0, kappa: 0.0}} # sharp disease null
|
|
harm: {effect: {relief: 0.3, kappa: 0.039}} # W0: disease-composite RD(A-B1) +5.1 pp at 60 months
|
|
benefit_harm: {effect: {relief: 2.0, kappa: 0.075}} # W0: RD -1.2 pp at 24 months, +3.1 pp at 60
|
|
# tuned in W0 with simulations/explore_scenarios.R (2e5 patients); the same mechanism is used in every world
|