The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Negative Control Diagnostics in causaldef

Deniz Akdemir

2026-03-26

Introduction

This vignette demonstrates how to use negative control outcomes to screen for residual confounding and compute a corresponding sensitivity bound using the causaldef package. Negative controls provide an empirical diagnostic for whether your adjustment strategy may have failed to remove confounding.

Theoretical Background

What is a Negative Control Outcome?

A negative control outcome (\(Y'\)) is a variable that:

  1. Shares confounders with the true outcome \(Y\) — it is affected by the same unmeasured variables \(U\) that confound the treatment-outcome relationship
  2. Is NOT causally affected by treatment \(A\) — the true causal effect of \(A\) on \(Y'\) is zero

The Diagnostic Logic

The key insight is:

If your adjustment strategy correctly removes confounding, then the residual association between \(A\) and \(Y'\) should be zero.

If you observe a non-zero association between \(A\) and \(Y'\) after adjustment, this indicates that confounding remains and your causal estimates may be biased.

Negative Control Sensitivity Bound (manuscript thm:nc_bound)

The causaldef package combines two ingredients:

  1. a screening test for residual association between treatment and the negative control after adjustment, and
  2. the manuscript’s negative control sensitivity bound (thm:nc_bound):

\[\delta(\hat{K}) \leq \kappa \cdot \delta_{NC}(\hat{K})\]

where: - \(\delta(\hat{K})\) is the true deficiency (what we want to know) - \(\delta_{NC}(\hat{K})\) is a negative-control association proxy (what we can measure) - \(\kappa\) is an alignment constant reflecting how well \(Y'\) proxies for \(Y\)’s confounding

Practical Example

Simulating Data with a Negative Control

Let’s create a dataset where we have: - An unmeasured confounder \(U\) - An observed covariate \(W\) (correlated with \(U\)) - Binary treatment \(A\) - Outcome \(Y\) affected by \(A\) and \(U\) - Negative control \(Y'\) affected only by \(U\) (not \(A\))

Creating the Causal Specification

We specify the causal problem including the negative control:

Running the Negative Control Diagnostic

Now we test whether our IPTW adjustment successfully removes confounding:

Interpreting the Results

The diagnostic returns:

Scenarios

Choosing Good Negative Control Outcomes

Ideal Properties

The best negative control outcomes have:

  1. Strong confounding alignment: \(Y'\) shares the same unmeasured confounders as \(Y\)
  2. Zero treatment effect: No plausible mechanism by which \(A\) affects \(Y'\)
  3. Measurable: Available in your dataset

Examples by Domain

Domain Treatment Outcome Possible Negative Control
Cardiovascular Statin use CVD events Accidental injuries
Oncology Chemotherapy Tumor response Hospital-acquired infections
Economics Job training Earnings in 1978 Earnings in 1974 (pre-treatment)
Epidemiology Vaccination Flu incidence Unrelated disease incidence

Combining with Deficiency Estimation

The negative control diagnostic complements deficiency estimation:

# Step 1: Estimate deficiency
def_results <- estimate_deficiency(
  spec,
  methods = c("unadjusted", "iptw", "aipw"),
  n_boot = 100
)

print(def_results)

# Step 2: Run negative control diagnostic on best method
best_method <- names(which.min(def_results$estimates))
nc_check <- nc_diagnostic(spec, method = best_method, n_boot = 100)

# Step 3: Compute policy bounds if assumptions not falsified
if (!nc_check$falsified) {
  bounds <- policy_regret_bound(
    def_results,
    utility_range = c(-5, 10),
    method = best_method
  )
  print(bounds)
} else {
  warning("Causal assumptions falsified. Consider additional covariates.")
}

Advanced: Estimating Kappa

The alignment constant \(\kappa\) affects the bound’s tightness. The default \(\kappa = 1\) is conservative. You can estimate \(\kappa\) from domain knowledge:

# If you believe Y' has 80% of Y's confounding structure:
nc_tight <- nc_diagnostic(
  spec,
  method = "iptw",
  kappa = 0.8,
  n_boot = 100
)

print(nc_tight)

Summary

Function Purpose
nc_diagnostic() Screen for residual association and compute a sensitivity bound
delta_nc Observable negative-control association proxy
delta_bound Upper bound on true deficiency
falsified Screening rejection of residual association

Negative control diagnostics provide a data-driven way to assess causal assumptions. Use them alongside deficiency estimation for robust causal inference.

References

  1. Akdemir, D. (2026). Constraints on Causal Inference as Experiment Comparison. DOI: 10.5281/zenodo.18367347. See thm:nc_bound (Negative Control Sensitivity Bound).

  2. Lipsitch, M., Tchetgen, E., & Cohen, T. (2010). Negative controls: A tool for detecting confounding and bias. Epidemiology, 21(3), 383-388.

  3. Shi, X., Miao, W., & Tchetgen Tchetgen, E. (2020). A selective review of negative control methods. Current Epidemiology Reports, 7, 190-202.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.