Survival-curve contrasts on a fitted hazard model

Description

Given a survatr_fit (chunk 1) and a named list of interventions, build the counterfactual person-period data under each intervention, predict the per-row hazard, cumulate within individual to get S^a_i(t), and average across individuals to get the population survival curve S^a(t) = (1/n) sum_i S^a_i(t). Derive risk / risk-difference / risk-ratio / RMST / RMST-difference contrasts from there.

No variance in this chunk. All se / ci_* columns come back as NA_real_; sandwich variance ships with chunk 3 (delta-method cross-time IF aggregation) and bootstrap with chunk 4.

Usage

## S3 method for class 'survatr_fit'
contrast(
  fit,
  interventions,
  times,
  type = NULL,
  cause = NULL,
  reference = NULL,
  ci_method = "none",
  conf_level = 0.95,
  n_boot = 500L,
  boot_ci = "percentile",
  parallel = "no",
  ncpus = 1L,
  seed = NULL,
  ...
)

Arguments

fit A survatr_fit.
interventions A named list of causatr_intervention objects (causatr::static(), causatr::shift(), causatr::scale_by(), causatr::threshold(), causatr::dynamic()). The element names are carried through to the intervention column of the result.
times Numeric vector of time points at which to evaluate the survival curve. Must all be elements of fit$time_grid — extrapolation beyond the observed grid is rejected with survatr_time_extrapolation.
type Estimand. For a single-event fit: one of “survival”, “risk”, “risk_difference”, “risk_ratio”, “rmst”, “rmst_difference” (default “risk_difference”). For a competing-risks fit (surv_fit(…, competing = )): one of “cif” (per-cause cumulative incidence), “cif_difference”, “cif_ratio” (default), or all-cause “survival” / “risk” (from the summed cause-specific hazards). Mixing a CIF estimand with a single-event fit (or vice versa) aborts with survatr_competing_type.
cause Competing-risks only. Integer vector selecting which cause(s) to report for the cif estimands, or NULL (the default) for all causes. Validated against the fitted causes; ignored for survival / risk and for single-event fits.
reference Name of the intervention used as the reference in difference / ratio contrasts. Defaults to the first name in interventions. Ignored by type = “survival”, “risk”, “rmst”, and “cif” (no pairwise contrast).
ci_method One of “none” (point estimates only), “sandwich” (delta-method cross-time IF aggregation via causatr:::prepare_model_if()), or “bootstrap” (resample individuals, refit the hazard model per replicate, percentile or Wald CIs). Default “none”.
conf_level Confidence level for the CIs when ci_method != “none”. Numeric scalar in (0, 1), default 0.95.
n_boot Integer; number of bootstrap replicates. Ignored when ci_method != “bootstrap”. Default 500L.
boot_ci One of “percentile” (sample-quantile CI) or “wald” (point estimate +/- z * sd(replicates)). Default “percentile”. Percentile is transform-invariant and is the safer default for ratios / RMST.
parallel One of “no”, “multicore”, “snow”; forwarded to boot::boot(). Default “no”.
ncpus Integer; number of CPUs for parallel bootstrap. Default 1L.
seed Integer scalar or NULL. When non-null, set.seed(seed) is called before the bootstrap loop so the replicate sequence is reproducible. Default NULL.
Unused; reserved for future chunks.

Value

A survatr_result list with estimates, contrasts, time_grid, type, reference, ci_method, and call components.

See Also

Other survatr_result methods: contrast(), forrest(), forrest.survatr_result(), plot.survatr_result(), print.survatr_result(), tidy.survatr_result()

Examples

library("survatr")

# Small rectangular person-period dataset: 40 ids over 5 periods.
set.seed(2)
n_id <- 40L
K <- 5L
pp <- data.frame(
  id = rep(seq_len(n_id), each = K),
  t = rep(seq_len(K), times = n_id),
  A = rep(rbinom(n_id, 1L, 0.5), each = K),
  Y = rbinom(n_id * K, 1L, 0.1)
)

fit <- surv_fit(pp, "Y", "A", ~1, "id", "t", time_formula = ~ factor(t))

ivs <- list(a1 = causatr::static(1), a0 = causatr::static(0))

# Point-estimate survival curves under each intervention.
contrast(fit, interventions = ivs, times = 1:5, type = "survival")
<survatr_result>
  Type:        survival
  Reference:   (none)
  CI method:   none
  Time grid:   [1, 5] (5 unique times)
  Estimates:   10 rows
  Contrasts:   0 rows

    intervention  time     s_hat   risk_hat    se ci_lower ci_upper     n
          <char> <int>     <num>      <num> <num>    <num>    <num> <int>
 1:           a1     1 0.8353902 0.16460980    NA       NA       NA    40
 2:           a1     2 0.6472768 0.35272325    NA       NA       NA    40
 3:           a1     3 0.4723363 0.52766373    NA       NA       NA    40
 4:           a1     4 0.3893941 0.61060590    NA       NA       NA    40
 5:           a1     5 0.3893941 0.61060591    NA       NA       NA    40
 6:           a0     1 0.9108374 0.08916256    NA       NA       NA    40
 7:           a0     2 0.7959226 0.20407739    NA       NA       NA    40
 8:           a0     3 0.6722328 0.32776724    NA       NA       NA    40
 9:           a0     4 0.6079052 0.39209483    NA       NA       NA    40
10:           a0     5 0.6079052 0.39209484    NA       NA       NA    40
# Risk difference with delta-method sandwich CIs.
contrast(
  fit,
  interventions = ivs,
  times = 1:5,
  type = "risk_difference",
  ci_method = "sandwich"
)
<survatr_result>
  Type:        risk_difference
  Reference:   a1
  CI method:   sandwich
  Time grid:   [1, 5] (5 unique times)
  Estimates:   10 rows
  Contrasts:   5 rows

   contrast  time    estimate         se   ci_lower   ci_upper
     <char> <int>       <num>      <num>      <num>      <num>
1: a0 vs a1     1 -0.07544723 0.05763982 -0.1884192 0.03752474
2: a0 vs a1     2 -0.14864586 0.10318090 -0.3508767 0.05358499
3: a0 vs a1     3 -0.19989649 0.13641365 -0.4672623 0.06746935
4: a0 vs a1     4 -0.21851107 0.15016893 -0.5128368 0.07581461
5: a0 vs a1     5 -0.21851107 0.15016893 -0.5128368 0.07581461