Negative-Control Outcome (Falsification) Analysis

Description

Runs the IP-weighted outcome model on a negative-control outcome – a cause of death that continued screening mammography cannot plausibly affect – and reports whether the estimated arm effect is consistent with the null. A clearly non-null association on the negative-control outcome would point to residual confounding or selection bias rather than a true screening effect.

Usage

negative_control_analysis(
  long_data,
  covariate_cols = NULL,
  weight_col = "wp99",
  outcome_col = "nc_dead_t1",
  arm_col = "arm",
  month_col = "month2",
  id_col = "id",
  cluster_id_col = id_col,
  max_month = 95L,
  rcs_knots = c(6, 48, 72),
  null_value = 1
)

Arguments

long_data A data frame in long format (one row per participant-arm-month), as produced by expand_to_long().
covariate_cols Character vector of column names to include as additional baseline adjustment terms. Set to NULL for no adjustment. Default: NULL.
weight_col Name of the column containing IPW weights. Set to NULL for unweighted estimation. Default: “wp99”.
outcome_col Name of the negative-control outcome column, as produced by expand_to_long(). Default: “nc_dead_t1”.
arm_col Name of the trial arm column. Default: “arm”.
month_col Name of the 0-indexed month-from-entry column. Default: “month2”.
id_col Name of the participant identifier column. Default: “id”.
cluster_id_col Name of the column to use for clustering standard errors. When non-NULL and the sandwich package is available, cluster-robust confidence intervals are returned. Defaults to id_col.
max_month Maximum month included in the model. Rows beyond this month are excluded. Default: 95L.
rcs_knots Numeric vector with at least 3 elements specifying the knots for the restricted cubic spline on time: the first element is the left boundary knot, the last element is the right boundary knot, and any middle elements are interior knots. Must have at least one interior knot. Default: c(6, 48, 72) (one interior knot at month 48).
null_value Odds ratio implying no arm effect. Default: 1.

Details

This ports the negative-control falsification check of García-Albéniz et al., which used death from cancer of the corpus uteri as the negative-control outcome (supplementary analysis). The function reuses fit_outcome_hr() on the negative-control outcome column produced by expand_to_long() when called with its nc_died_col argument (nc_dead_t1 by default). The returned odds ratio approximates the hazard ratio for the STOPBASE arm relative to CONTINUE on the negative-control outcome; absent bias it should sit near null_value, and null_consistent records whether the confidence interval covers it.

Value

A named list:

  • or: Odds ratio for the STOPBASE arm on the negative-control outcome.

  • or_ci: 95% confidence interval for or.

  • null_consistent: TRUE when or_ci covers null_value, i.e., the falsification test passes (no detectable effect on the negative control).

  • model: The fitted stats::glm object.

References

García-Albéniz X, Uno H, Bhatt DL, McArdle PH, Joffe MM, Hernán MA. Continuation of Annual Screening Mammography and Breast Cancer Mortality in Women Older Than 70 Years: A Prospective Observational Study. Ann Intern Med. 2020;172(6):381-389. doi:10.7326/M18-1199

See Also

fit_outcome_hr() for the underlying model and expand_to_long() (argument nc_died_col) for building the negative-control outcome.

Examples

Code
library("ettbc")

sim <- simulate_screening_cohort(n = 800, seed = 4, negative_control = TRUE)
cloned <- clone_censor(
  sim$cohort, sim$screening_mammograms, sim$diagnostic_mammograms
)
long <- expand_to_long(cloned, nc_died_col = "nc_death")
long <- augment_long_covariates(
  long, sim$screening_mammograms, sim$diagnostic_mammograms
)
fit <- fit_screening_propensity(long)
weighted <- compute_ipw_weights(fit$data, pred_prob_col = "p_scrmammo")
nc <- negative_control_analysis(weighted)
nc$or
[1] 0.5646123
Code
nc$null_consistent
[1] TRUE