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,
  q = 0.5,
  reference = NULL,
  ci_method = "none",
  conf_level = 0.95,
  n_boot = 500L,
  boot_ci = "percentile",
  parallel = "no",
  ncpus = 1L,
  seed = NULL,
  cluster = 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”, “rmtl” (restricted mean time lost, t - RMST), “rmtl_difference”, or “quantile” (survival-time quantile / median; default “risk_difference”). For a competing-risks fit (surv_fit(…, competing = )): one of “cif” (per-cause cumulative incidence), “cif_difference”, “cif_ratio” (default), “yll” (per-cause years of life lost, int F^(j)), all-cause “survival” / “risk” / “rmst” / “rmtl”, or all-cause “quantile” (from the summed cause-specific hazards). Mixing a CIF estimand with a single-event fit (or vice versa) aborts with survatr_competing_type; “yll” on a single-event fit aborts with survatr_yll_needs_cr.
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.
q For type = “quantile”, the quantile level(s) of the survival-time distribution to report – a numeric vector with every entry in (0, 1) (default 0.5 = median). The result is indexed by q (one tau_hat per (intervention, q)) rather than by time. Aborts with survatr_quantile_unreached when the curve never crosses 1 - q on the grid, and survatr_bad_q for out-of-range q. Ignored for other types.
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.
cluster NULL (the default; per-individual sandwich) or a single column name in the fit’s person-period data identifying the independent sampling cluster (site, household, provider, repeated enrolment). The label must be constant within id and have no NA. When supplied, the sandwich variance is cluster-robust (the per-individual influence functions are summed within cluster before the cross-product) and the bootstrap resamples whole clusters. cluster = “<id-column>” reproduces the per-individual sandwich exactly (singleton clusters). Supported for gcomp, IPW, IPCW, longitudinal ICE-hazard, and competing-risks fits.
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