D56: limb MALE (CLTI, major amputation, open bypass) as primary outcome; MALE incl. repeat revascularization to supplement

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-28 16:39:59 -04:00
co-authored by Claude Opus 5.5
parent d369a16208
commit 3aa6c1c5b3
12 changed files with 37 additions and 33 deletions
+2 -2
View File
@@ -11,8 +11,8 @@ jobs <- CJ(world = names(raw$worlds), scenario = names(raw$scenarios), sorted =
res <- parallel::mclapply(seq_len(nrow(jobs)), function(i) {
w <- jobs$world[i]; s <- jobs$scenario[i]
par <- load_params(w, s)
rbind(rct_truth(par, "realistic", n = 1e6)[outcome %in% c("male", "disease", "nco1", "nco2")],
rct_truth(par, "ideal", n = 1e6)[outcome %in% c("male", "disease", "nco1", "nco2")])
rbind(rct_truth(par, "realistic", n = 1e6)[outcome %in% c("limb", "male", "disease", "rr", "nco1", "nco2")],
rct_truth(par, "ideal", n = 1e6)[outcome %in% c("limb", "male", "disease", "rr", "nco1", "nco2")])
}, mc.cores = cores)
bad <- vapply(res, inherits, TRUE, "try-error")
if (any(bad)) stop(res[bad][[1]])
+3 -3
View File
@@ -67,16 +67,16 @@ perf[, `:=`(mcse_cover = sqrt(cover_own * (1 - cover_own) / reps),
fwrite(perf, file.path(outdir, "perf.csv"))
# ---- negative controls as bias detectors (plan 10) ------------------------------------
# One unit = world x scenario x design x variant x replicate. Bias is in the MALE RD
# One unit = world x scenario x design x variant x replicate. Bias is in the limb-MALE RD (D56)
# against the method's own estimand; a control "flags" when its 95% CI excludes 0.
m <- d[analysis == "main" & design != "landmark_m5" & variant %in% c("V1_ignore", "V2_cluster", "V3_random", "V4_within") &
contrast %in% c("early_none", "A_B1", "now_not")]
u <- c("world", "scenario", "design", "variant", "rep")
flag <- function(x) x$lo > 0 | x$hi < 0
nc <- m[outcome == "male", c(..u, "est", "own")][, err := est - own]
nc <- m[outcome == "limb", c(..u, "est", "own")][, err := est - own]
nc <- merge(nc, m[outcome == "nco1", c(..u)][, nco1 := flag(m[outcome == "nco1"])], by = u, all.x = TRUE)
nc <- merge(nc, m[outcome == "nco2", c(..u)][, nco2 := flag(m[outcome == "nco2"])], by = u, all.x = TRUE)
ne <- d[analysis == "nce" & outcome == "male" & contrast %in% c("early_none", "A_B1")]
ne <- d[analysis == "nce" & outcome == "limb" & contrast %in% c("early_none", "A_B1")]
nc <- merge(nc, ne[, c(..u)][, nce := flag(ne)], by = u, all.x = TRUE)
nc[, any_nc := nco1 | nco2 | fifelse(is.na(nce), FALSE, nce)]
nc[, cell_bias := mean(err), by = .(world, scenario, design, variant)]
+1 -1
View File
@@ -13,7 +13,7 @@ cfg <- yaml::read_yaml("simulations/config/experiments.yml")
n <- cfg$scales$draft$n_patients
outdir <- "results/bootstrap"; dir.create(outdir, showWarnings = FALSE, recursive = TRUE)
designs <- c("naive", "landmark", "landmark_m5", "ccw", "seq")
outs <- c(male = "t_male", disease = "t_disease")
outs <- c(limb = "t_limb", male = "t_male", disease = "t_disease")
jobs <- CJ(world = c("W0", "WR"), scenario = c("null", "harm"), rep = seq_len(reps), sorted = FALSE)
jobs[, file := file.path(outdir, sprintf("%s_%s_rep%03d.csv", world, scenario, rep))]
+1 -1
View File
@@ -23,7 +23,7 @@ one_job <- function(i) {
out <- list()
with_v2 <- function(r) if (r$variant[1] == "V1_ignore") # same fit, two SEs
rbind(r, copy(r)[, `:=`(variant = "V2_cluster", se = se_cluster)]) else r
nce_out <- c(male = "t_male", disease = "t_disease")
nce_out <- c(limb = "t_limb", male = "t_male", disease = "t_disease")
for (v in g$variants) {
out[[length(out) + 1]] <- with_v2(run_designs(rec, unlist(g$designs), v))[, analysis := "main"]
if (isTRUE(g$nce))