← Methods repository
CONCEPTINTERMEDIATEPYTHON · R · SAS5 citations

Case-Crossover Design

A self-controlled design in which each case serves as its own control, contrasting exposure during a hazard ("case") window immediately before an acute event with exposure during one or more earlier referent ("control") windows in the same person, to estimate the transient effect of an intermittent exposure on the risk of abrupt event onset.

Study Designself-controlledwithin-persontransient-exposureacute-eventconditional-logistictrigger-studypharmacoepidemiologyexposure-time-trend
On this page
Methods reference only. Use primary source citations and local policy before applying this in a study protocol, regulatory submission, payer dossier, or clinical decision.
In plain language

A case-crossover study asks: was the patient more likely to be taking a short-acting drug in the days just before their emergency hospitalization than they were in calmer periods months earlier? Instead of comparing the patient to other people, the design compares the same person to themselves — the hazard window (a brief period right before the event) versus earlier referent windows when no event occurred. Because both windows come from the same person, anything that is stable about them — their chronic conditions, genetics, income, general frailty — automatically cancels out. The trade-off is that it only works when the exposure is intermittent (taken sometimes but not always) and the event is sudden and well-dated, like a hospitalization.

When to use it
Short-acting/intermittent exposure and an acute, well-dated event where unmeasured stable confounding would dominate a cohort analysis.
When suspected confounders are stable within persons and the exposure is genuinely transient.
Single acute event with a short induction period; choose SCCS for recurrent events or vaccine risk-interval analyses.
Watch out for
Estimates only the transient-trigger OR, not absolute risk or chronic-exposure effects; vulnerable to within-person exposure-time trends and carryover that a cohort with an external comparator can absorb.
Cannot study non-time-varying exposures; less efficient when within-person exposure is rare or near-constant; trades confounding bias for exposure-trend bias.
Less natural for recurrent events; does not model the full observation time or age/time effects explicitly as SCCS does.

The case-crossover design studies whether a transient exposure triggers an abrupt event by comparing, within each case, the exposure status during a short window just before the event (the case/hazard window) with exposure during one or more referent/control windows in that same individual at an earlier time. There is no separate control group: each case is matched to itself. Analytically it is a matched case-control study where the matched sets are person-periods, so the natural estimator is conditional (stratum = person) logistic regression, and the estimand is the odds ratio for the transient effect of exposure on event onset within the hazard window (an approximation of the rate ratio under the usual rare-event/incidence-density logic of Mittleman, Maclure & Robins).

Core conceptual distinction — why self-controlled

Because both windows come from the same person, every time-invariant characteristic is matched out by design: genetics, sex, baseline comorbidity, frailty, socioeconomic status, chronic channeling, and any other stable confounder — measured or not — cancels in the within-person contrast. This is the design's unique selling point relative to cohort or conventional case-control designs, which must measure and adjust for those confounders. The price is that the design controls only time-invariant confounding; anything that varies within a person over the spacing between windows (acute illness, season, day of week, secular trends in exposure prevalence) is not controlled and can bias the estimate badly.

Estimand and assumptions

Under (i) a transient exposure with a well-defined effect (induction/hazard) period, (ii) a stable distribution of exposure over time within persons (the "no exposure-time trend" assumption), (iii) no carryover of effect from the case window into the referent windows (and vice versa), and (iv) the event not itself altering subsequent exposure, the conditional-logistic OR estimates the incidence rate ratio for the acute triggering effect. Violations of (ii) and (iii) are the dominant failure modes and motivate the case-time-control and case-case-time-control extensions below.

Pros, cons, and trade-offs

  • vs cohort / new-user designs: Case-crossover needs no comparator cohort and is immune to all stable confounding, which is decisive when the suspected confounders are chronic and hard to measure in claims (frailty, lifestyle). Cost: it answers only the transient-trigger question, gives an OR not an absolute risk, has no information on chronic-exposure effects, and is vulnerable to within-person time trends that a cohort with an external comparator can absorb. Prefer for short-acting drugs and acute events where confounding-by-indication and unmeasured frailty would wreck a cohort.
  • vs conventional / nested case-control: Removes between-person confounding entirely and needs no control selection, eliminating one source of selection bias. Cost: it cannot study non-time-varying exposures, is less efficient when exposure is rare or near-constant within persons, and shifts the threat from confounding to exposure-trend bias.
  • vs self-controlled case series (SCCS): Both are self-controlled and remove time-invariant confounding. SCCS models the full observation time with a Poisson/conditional-Poisson model, handles recurrent events naturally, requires the event not to censor/curtail observation (or a modified SCCS), and is well suited to vaccine-safety risk-interval analyses. Case-crossover samples discrete referent windows, needs only the cases, and is simpler when the exposure is sharply intermittent and the event is acute and rare. Prefer SCCS for recurrent events or when modeling age/time effects explicitly; prefer case-crossover for a single acute event triggered by a sharply transient exposure.
  • vs case-time-control / case-case-time-control: When background exposure prevalence is changing over calendar time (e.g., a drug's use is rising), the plain case-crossover OR is biased by that exposure-time trend. Case-time-control (Suissa 1995) adds a separate control group to estimate and subtract the trend; case-case-time-control (Wang, Schneeweiss) uses future cases as the control series to also absorb within-person trends from disease progression. These are the correct fixes, not heavier covariate adjustment.

When NOT to use — and when it is actively misleading or dangerous

  • Chronic / continuous exposure. If exposure is essentially constant across the case and referent windows (a maintenance statin taken daily for years), there is no within-person contrast and the design is uninformative or biased toward the null. Use a cohort/new-user design instead.
  • Exposure with a secular time trend. If the drug's prevalence is rising (or falling) over calendar time, exposure is systematically more (or less) likely in the more recent case window than in earlier referent windows for reasons unrelated to the event, producing a spurious OR. This is the canonical case-crossover failure and is exactly what case-time-control repairs. Bidirectional sampling (referent windows both before and after the event) partly mitigates it but assumes the event does not affect future exposure.
  • Carryover / long or ill-defined effect window. If the effect persists across both windows, or the induction period is long relative to window spacing, exposure "bleeds" into the referent window and attenuates the contrast. Case-crossover demands a short, well-characterized hazard period.
  • Event alters subsequent exposure (within-person reverse causation). If a prodrome of the event changes exposure (a patient with early symptoms stops or starts a drug), unidirectional (before-only) sampling is biased; bidirectional sampling is invalid because post-event exposure is affected by the event.
  • Depletion of susceptibles / first-event-only chronic use. For drugs where susceptible patients have their event early in treatment, the within-person exposure-event association is distorted; SCCS or a new-user cohort is safer.

Operational sampling choices (these are design decisions, not nuisances)

Unidirectional sampling draws referent windows only before the event (mandatory when the event can affect future exposure or cause death); it is the more conservative default in pharmacoepidemiology. Bidirectional sampling draws referents both before and after the event and controls for within-person time trends, but is valid only when post-event exposure is unaffected by the event. The number and spacing of referent windows trade efficiency against the exposure-trend and carryover assumptions: more referent windows improve precision (Mittleman, Maclure & Robins show the relative efficiency gains) but widen the calendar span over which the no-trend assumption must hold. A further choice is the point-in-time approach (was the person exposed on the index day of each window?) vs the window/hazard-period approach (was there any exposure within a multi-day hazard period?); in claims the window approach with a `days_supply`-defined exposure interval is usually required because dispensing is bursty (Hallas et al. 2024).

Data-source operational depth

  • Claims (FFS): Exposure is reconstructed from pharmacy fills — a person is "exposed" on a given day if a dispensing's `[fill_date, fill_date + days_supply)` interval covers that day (apply a grace period and stockpiling rule, and account for 90-day mail-order and free samples that distort `days_supply`). The event date is the index claim for the acute outcome. Require continuous medical + pharmacy enrollment spanning the entire span from the earliest referent window through the event so that absence of a fill is true non-exposure, not unobserved dispensing. Failure modes: Medicare Advantage and capitated person-time lack fee-for-service claims, so exposure in a referent window can be missing rather than absent — restrict to enrollees with the relevant medical + Part D / pharmacy benefit and exclude MA-only person-time across every window. Outpatient-only acute events may be miscoded or undated; prefer inpatient/ED principal-diagnosis events with a clean admission date as the anchor.
  • EHR: Exposure is the order/administration, not the fill, and is visit-driven, so the referent windows are populated only when the patient interacts with the system — differential visit intensity around the event (more contact just before an MI) manufactures a spurious within-person exposure trend. Link to dispensing where possible and restrict to exposures routinely captured (e.g., inpatient MAR) rather than self-managed OTC drugs.
  • Registry / linked: Registries give well-adjudicated, well-dated acute events (the ideal anchor) but rarely complete longitudinal exposure; link to claims for the fill history and to a death index, since unidirectional sampling is mandatory when the event is fatal (no post-event windows exist).

Worked claims example

Question: does short-term NSAID exposure trigger acute upper-GI bleeding among older adults in a Medicare FFS + Part D database?

  1. Cases: the first hospitalization with a principal ICD-10 diagnosis of acute upper-GI hemorrhage; the event date is the admission date.
  2. Enrollment: require continuous Parts A/B/D and exclude any MA-only person-time over the 6 months preceding the event so every window is FFS-observable.
  3. Exposure: a day is NSAID-exposed if any non-aspirin NSAID dispensing's `[fill_date, fill_date + days_supply + 3-day grace)` interval covers it.
  4. Hazard (case) window: the 7 days immediately before the event date.
  5. Referent (control) windows: four non-overlapping 7-day windows ending 30, 60, 90, and 120 days before the event (unidirectional, because the bleed and any hospitalization can alter subsequent drug use).
  6. Classify each window as exposed/unexposed by the rule in (3), creating one stratum per person with one case-window row and four referent-window rows.
  7. Fit conditional logistic regression stratified on `person_id`; the exponentiated coefficient is the OR for the transient NSAID-triggering effect.
  8. Sensitivity: vary the hazard-window length (3/7/14 days) and grace period; run a case-time-control analysis to net out the secular rise in NSAID use; and test a negative-control exposure (a drug with no plausible acute GI-bleed effect) — its OR should be ~1.

Decision diagram

timeline
  title Case-crossover windows for one subject (unidirectional, referent to event date)
  120 days before : Referent window 4 : exposed? assessed from days_supply coverage
  90 days before : Referent window 3 : exposed? assessed from days_supply coverage
  60 days before : Referent window 2 : exposed? assessed from days_supply coverage
  30 days before : Referent window 1 : exposed? assessed from days_supply coverage
  Event date : Case / hazard window : exposed? assessed in the 7 days before the event
One subject contributes a single case (hazard) window just before the acute event and four earlier referent windows. Conditional logistic regression compares case-window exposure to referent-window exposure within the person, so all time-invariant confounders cancel.
flowchart LR
  U[Time-invariant confounders<br/>genetics, sex, chronic comorbidity, SES] -. blocked by within-person matching .-> X
  V[Time-varying factors<br/>exposure-time trend, season, acute illness] --> X[Transient exposure<br/>in window]
  V --> Y[Acute event onset]
  X --> Y
  classDef blocked fill:#e8f5e9,stroke:#2e7d32;
  classDef threat fill:#fdecea,stroke:#c62828;
  class U blocked;
  class V threat;
Why the design works and where it fails. Stable confounders (U) are matched out by the within-person contrast (dashed blocked path). Time-varying factors (V) - especially secular exposure-time trends - remain open backdoor paths and are the motivation for case-time-control and bidirectional sampling.

Worked example

Scenario

Two older adults were each hospitalized with an acute upper-gastrointestinal bleed. We want to know whether taking ibuprofen in the days just before the bleed raised their risk. For each patient we define one hazard window (the 7 days immediately before admission) and four referent windows (the 7-day periods ending 30, 60, 90, and 120 days earlier). We then look up whether a pharmacy claim for ibuprofen covered any day in each window, using the rule: a fill is 'on board' for every calendar day from the fill date through the fill date plus the days supplied. If the drug turns up in the hazard window more often than in the referent windows — across many patients like these two — that is evidence of a triggering effect.

Dataset

Pharmacy fill records for two patients. Each row is one prescription dispensed; days_supply tells us how many days that bottle was meant to last. A day is considered 'ibuprofen-exposed' if it falls within [fill_date, fill_date + days_supply).

person_idfill_datedrugdays_supply
10012023-09-05ibuprofen14
10022023-08-18ibuprofen7
FIG. 1 — DESIGN TIMELINE
Timeline for Patient 1001 running from May 2023 to September 15 2023. Four 7-day bands labeled Referent 4 through Referent 1 are shaded blue (unexposed) at 120, 90, 60, and 30 days before the event. A 14-day ibuprofen fill bar starts September 5. The hazard window (September 8-14) is shaded orange (exposed) immediately before the GI bleed admission marker on September 15.
Each horizontal band is one 7-day window assessed for ibuprofen exposure in Patient 1001. The four referent windows (blue, UNEXPOSED) represent calm periods months earlier; the hazard window (orange, EXPOSED) sits right before the admission. Because this one patient's hazard window is exposed while all four referent windows are not, the comparison screams 'the drug was unusually present just before the event.'...

Steps

1Patient 1001 had a GI bleed admission on 2023-09-15. Their ibuprofen fill on Sep 5 covers Sep 5 through Sep 18 (14 days). The hazard window runs Sep 8–Sep 14 — all seven days fall inside the fill's coverage, so this window is EXPOSED.
2Patient 1001's four referent windows (ending Aug 16, Jul 17, Jun 17, May 17) all fall outside any fill. No ibuprofen was on board during any of them, so all four are UNEXPOSED.
3Patient 1002 had a GI bleed admission on 2023-09-28. Their ibuprofen fill on Aug 18 covers Aug 18 through Aug 24 (7 days). The hazard window runs Sep 21–Sep 27 — well after the fill expired — so this window is UNEXPOSED.
4Patient 1002's referent window ending Aug 29 spans Aug 23–Aug 29. The fill's last covered days are Aug 23 and Aug 24, which fall inside this window, so referent window 1 is EXPOSED. The remaining three referent windows (ending Jul 30, Jun 29, May 30) have no fill coverage and are UNEXPOSED.
5Now count the informative pairs. A 'discordant pair' is any (hazard window, referent window) combination where one is exposed and the other is not — these pairs carry all the information about whether hazard-window exposure is unusually high.
6Patient 1001 contributes 4 discordant pairs: hazard=EXPOSED paired with each of 4 UNEXPOSED referent windows. Patient 1002 contributes 1 discordant pair: hazard=UNEXPOSED paired with referent window 1=EXPOSED. The other three of Patient 1002's referent windows are concordant (both unexposed) and contribute nothing.
7Estimated OR = (pairs where hazard exposed, referent not) ÷ (pairs where referent exposed, hazard not) = 4 ÷ 1 = 4.0.

Result

OR = 4 / 1 = 4.0 — across these two patients the ibuprofen-exposure odds were four times higher in the hazard windows than in the matched referent windows, consistent with NSAID use triggering acute GI bleeding. (In a real study, hundreds of cases would be pooled via conditional logistic regression to get a stable estimate with a confidence interval.)

Trade-offs

vs. Cohort / new user design
Pros of this
Eliminates all time-invariant confounding (measured or not) by within-person matching; needs no comparator cohort; robust to unmeasured chronic frailty/channeling.
vs. Conventional / nested case control
Pros of this
Removes between-person confounding entirely and needs no separate control selection, eliminating control-selection bias.
vs. Self controlled case series (SCCS)
Pros of this
Simpler when the event is a single acute, rare occurrence triggered by a sharply intermittent exposure; uses only the cases and discrete referent windows.
vs. Case time control / case case time control
Pros of this
Simpler to specify and communicate; needs only the cases.
Cons of this
Provides no protection against background exposure-time trends; the plain OR is biased when prescribing prevalence changes over calendar time.
When to prefer When exposure prevalence is stable over the study window; otherwise use case-time-control (secular trend) or case-case-time-control (also within-person/progression trends).

Runnable example

Build case/referent person-period rows from claims and fit conditional logistic regression. Required inputs (cleaned, de-duplicated): events : one acute event per person -> person_id, event_date (datetime) rx : pharmacy fills -> person_id, fill_date (datetime), days_supply (int) # exposure of interest only enroll :...

requires: pandas · numpy · statsmodels
import numpy as np
import pandas as pd
import statsmodels.api as sm

HAZARD_DAYS = 7          # length of each window
REFERENT_LAGS = [30, 60, 90, 120]  # days before event_date at which each referent window ENDS
GRACE = 3                # days_supply grace to bridge late refills

def _covered(days_set: set, win_end, win_len=HAZARD_DAYS) -> int:
    """1 if any exposed day falls inside the window [win_end - win_len + 1, win_end]."""
    win = {win_end - pd.Timedelta(days=d) for d in range(win_len)}
    return int(bool(days_set & win))

def build_case_crossover(events: pd.DataFrame, rx: pd.DataFrame,
                         enroll: pd.DataFrame) -> pd.DataFrame:
    # Earliest day any window can reach back to; used for the enrollment-observability check.
    earliest_lag = max(REFERENT_LAGS) + HAZARD_DAYS
    ev = events.merge(enroll, on="person_id")
    ev["covers"] = ((ev["enroll_start"] <= ev["event_date"] - pd.Timedelta(days=earliest_lag)) &
                    (ev["enroll_end"]   >= ev["event_date"]) &
                    (~ev["ma_only"]))                 # every window must be FFS-observable
    ok = ev.loc[ev["covers"], "person_id"].unique()
    ev = events[events["person_id"].isin(ok)].copy()

    # Per person, the set of calendar days covered by the exposure of interest.
    rx = rx[rx["person_id"].isin(ok)].copy()
    rx["start"] = rx["fill_date"]
    rx["end"]   = rx["fill_date"] + pd.to_timedelta(rx["days_supply"] + GRACE, unit="D")
    exposed_days = {}
    for pid, g in rx.groupby("person_id"):
        days = set()
        for _, r in g.iterrows():
            days |= {r["start"] + pd.Timedelta(days=d)
                     for d in range((r["end"] - r["start"]).days)}
        exposed_days[pid] = days

    rows = []
    for _, r in ev.iterrows():
        pid, e = r["person_id"], r["event_date"]
        days = exposed_days.get(pid, set())
        # Case window: the HAZARD_DAYS immediately before (and including) the event date.
        rows.append({"person_id": pid, "is_case_window": 1,
                     "exposed": _covered(days, e)})
        # Referent windows: each ends `lag` days before the event date (unidirectional).
        for lag in REFERENT_LAGS:
            rows.append({"person_id": pid, "is_case_window": 0,
                         "exposed": _covered(days, e - pd.Timedelta(days=lag))})
    return pd.DataFrame(rows)

def fit_case_crossover(df: pd.DataFrame):
    # Conditional logistic = stratified-by-person logit of the case-window indicator on exposure.
    model = sm.ConditionalLogit(endog=df["is_case_window"],
                                exog=df[["exposed"]],
                                groups=df["person_id"])
    res = model.fit(disp=False)
    or_ = np.exp(res.params["exposed"])
    ci = np.exp(res.conf_int().loc["exposed"])
    return res, or_, (ci[0], ci[1])

Citations

FOUNDATIONAL / METHODS
  1. [1]Maclure M. The case-crossover design: a method for studying transient effects on the risk of acute events. American Journal of Epidemiology. 1991;133(2):144-153.
  2. [2]Maclure M, Mittleman MA. Should we use a case-crossover design? Annual Review of Public Health. 2000;21:193-221.
  3. [3]Mittleman MA, Maclure M, Robins JM. Control sampling strategies for case-crossover studies: an assessment of relative efficiency. American Journal of Epidemiology. 1995;142(1):91-98.
APPLIED EXAMPLES
  1. [4]Delaney JAC, Suissa S. The case-crossover study design in pharmacoepidemiology. Statistical Methods in Medical Research. 2009;18(1):53-65.
  2. [5]Suissa S. The case-time-control design. Epidemiology. 1995;6(3):248-253.