← Methods repository
concept

Target Trial Emulation

A causal-inference framework that first writes the protocol of the hypothetical pragmatic randomized trial that would answer the question (eligibility, treatment strategies, assignment, time zero, follow-up, outcome, causal contrast, analysis), then emulates each component in observational data so that the design-induced biases of naive analyses — immortal time, prevalent-user, and time-zero misalignment — are prevented by construction.

Framework_Standardcausal_inferencetarget_trialprotocol_specificationimmortal_time_preventionestimandper_protocolcomparative_effectiveness
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

Target trial emulation is a disciplined way to design an observational study by first writing down the exact protocol of the randomized trial you wish you could run, then mimicking each piece of that protocol in real-world records such as insurance claims or electronic health records. The key discipline it enforces is that three things must happen on the same day: confirming the patient is eligible, assigning them to a treatment strategy, and starting to count follow-up time. When those three things start at different times, a patient can rack up disease-free days before ever being labeled as treated, which makes the treated group look artificially healthier than it really is.

Target trial emulation (TTE)

is not a study design or an estimator; it is a discipline for designing an observational comparative study by explicitly specifying the protocol of the randomized trial you wish you could run — the "target trial" — and then mapping each of its components onto real-world data (Hernán & Robins). The seven protocol components are: (1) eligibility criteria, (2) treatment strategies being compared, (3) assignment procedure, (4) time zero (the moment eligibility, strategy assignment, and follow-up start are all aligned), (5) follow-up period, (6) outcome, and (7) causal contrast and statistical analysis. The single most important discipline TTE enforces is that eligibility, treatment assignment, and the start of follow-up must be evaluated at the same time zero. Most notorious RWE blunders — immortal time bias, prevalent-user bias, and adjusting for post-baseline variables — are failures to align time zero, and writing the target-trial protocol surfaces them before any data are touched.

Core estimand distinction

TTE forces a choice that naive analyses leave implicit. The intention-to-treat (ITT) emulation contrasts treatment strategies assigned at time zero and follows everyone under their initiating strategy regardless of later adherence or switching — it estimates the effect of being assigned to strategy A vs B. The per-protocol emulation contrasts the strategies under sustained adherence; because adherence is not randomized, it requires censoring at deviation plus inverse-probability-of-censoring weighting, or clone-censor-weight for sustained "initiate and remain on" strategies, to handle time-varying confounding and informative censoring. These are different causal questions with different identifying assumptions, not two ways of computing the same number. Separately, the survival estimand must be pre-specified — cause-specific hazard, cumulative incidence (subdistribution), or risk difference at a fixed horizon — because under competing risks they answer different questions and a hazard ratio is not a risk contrast.

Pros, cons, and trade-offs

- vs the naive "ever vs never user" or prevalent-user cohort: TTE prevents immortal time, prevalent-user bias, and time-zero misalignment by construction rather than by post-hoc adjustment, and it makes the estimand explicit and auditable against a trial protocol. Cost: more upfront design work, a narrower (initiation) population, and — for per-protocol questions — g-methods that are harder to communicate than a single adjusted hazard ratio. - vs an unstructured active-comparator new-user (ACNU) analysis: TTE is the protocol-specification layer around ACNU, not a competitor; ACNU is the usual analytic engine of a two-drug TTE. TTE adds value precisely when the strategies are sustained or dynamic (grace periods, "treat until progression", dose escalation) where the simple ACNU initiation contrast is insufficient and clone-censor-weight is needed. Prefer plain ACNU when a static, initiation-only (ITT-like) contrast answers the question; add the full TTE/clone-censor-weight machinery only when the protocol genuinely requires a sustained per-protocol estimand. - vs a head-to-head RCT: TTE is faster, cheaper, and covers populations and long horizons trials cannot, and a registry-based randomized trial is itself a randomized form of target-trial emulation. Cost: TTE cannot fix unmeasured confounding (assignment is not randomized), so it relies on the no-unmeasured-confounding-at-time-zero assumption and on negative controls, E-values, and quantitative bias analysis to bound residual bias.

When to use

Virtually any comparative effectiveness or safety question about initiating or sustaining a treatment strategy in claims, EHR, registry, or linked data — especially when a head-to-head RCT is infeasible and a regulatory or HTA audience expects explicit bias mitigation. Use it as the design scaffold whenever there is real risk of immortal time (the "treatment" is defined by an event that takes time to occur, e.g., transplant, responder, or completed-course definitions), prevalent-user contamination, or a treatment strategy that unfolds over time.

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

- No well-defined intervention / a non-modifiable "exposure". TTE requires that you can name a hypothetical trial that randomizes the strategy at a single time zero. "Effect of obesity" or "effect of a biomarker level" has no well-defined intervention and no coherent time zero; forcing TTE manufactures a spurious estimand. Use it for drug/procedure strategies, not for fixed traits. - Positivity is violated. If one strategy is never chosen for an identifiable subgroup at time zero (e.g., a drug contraindicated in CKD-4), the trial could not have randomized those patients; emulating it anyway extrapolates into a region with no support and the weighted estimate is driven by a handful of influential clones. - Time zero cannot be reconstructed from the data. When the data cannot pin the moment eligibility and strategy assignment coincide (e.g., EHR with no reliable medication-start date), an emulated time zero invites the very immortal time the framework exists to prevent — it gives a false sense of rigor. - A per-protocol estimand is reported but informative censoring is ignored. Censoring at non-adherence without inverse-probability-of-censoring weighting reintroduces, under a sophisticated-looking protocol, exactly the selection bias TTE is meant to remove. This is more dangerous than a naive analysis because the protocol lends it false credibility.

Data-source operational depth

- Claims (FFS or commercial): Strong for operationalizing eligibility (continuous medical + pharmacy enrollment, drug-free washout), strategy assignment (first qualifying NDC fill = time zero), and outcomes (validated diagnosis/procedure algorithms). Failure modes: (a) Medicare Advantage person-time has no FFS claims, so "no prior fill" during washout can be missingness, not a true drug-free period — require Parts A/B/D (or commercial medical+pharmacy) for the entire washout and exclude MA-only spans. (b) Immortal time in procedure/responder studies — defining a strategy by an event that takes time to occur (received transplant, completed 6 cycles) builds guaranteed survival into one arm; the fix is cloning at time zero and censoring clones when their data diverge from the assigned strategy, never classifying on a future event. (c) Differential competing risks by exposure in the elderly — when one strategy is preferentially used in sicker patients, death competes differentially with the outcome; report cumulative incidence (Fine-Gray or Aalen-Johansen), not just cause-specific hazards. - EHR: Adds labs, problem lists, and severity for sharper eligibility, but initiation is the order/administration, not the dispensing; without linked pharmacy data the actual start date — and thus time zero — is uncertain. Visit-driven capture makes loss to follow-up informative; define the observation window explicitly and treat out-of-system gaps as potential censoring, not as continued eligibility. - Registry: Best for adjudicated outcomes, disease severity, and stage at time zero, but typically weak for complete drug exposure; link to claims for the full fill history and to a death index to firm up censoring. A registry-based randomized trial is the gold-standard randomized form of TTE. - Linked claims–EHR–vital records: The ideal substrate (EHR severity + claims completeness + reliable mortality), but order/fill/service-date discrepancies must be reconciled before time-zero assignment, and the linkable subset introduces selection that should be assessed for transportability to the target population.

Worked claims example — protocol-to-emulation

Question: among adults with type 2 diabetes and stage-3 CKD, does initiating an SGLT2 inhibitor vs initiating a DPP-4 inhibitor reduce 3-year MACE? Emulate the trial component by component in a commercial + Medicare FFS database: 1. Eligibility — age >=18, >=2 T2D diagnoses, an eGFR/CKD-3 marker, and 365 days of continuous A/B/D (or commercial medical+pharmacy) enrollment before the first study fill; assessed at time zero only. 2. Treatment strategies — "initiate SGLT2i" vs "initiate DPP-4i"; washout requires no fill of either class in the 365-day lookback (both arms are incident users). 3. Assignment — emulated by the class of the NDC dispensed on the index fill; confounding-by-indication addressed downstream with a high-dimensional propensity score built only from the [index_date-365, index_date] window. 4. Time zero — the date of that first qualifying fill; eligibility, assignment, and follow-up all start here, so there is no immortal time and no adjustment for post-initiation variables. 5. Follow-up — from time zero to the first validated MACE event, censoring at disenrollment, death from other causes (a competing risk), end of data, or 3 years. 6. Outcome — MACE via a pre-specified inpatient MI/stroke + cardiovascular-death algorithm; report cumulative incidence at 3 years, not only a hazard ratio. 7. Causal contrast / analysisITT emulation: follow each initiator under the assigned class regardless of later switching/discontinuation (PS-weighted risk difference at 3 years). Per-protocol emulation: additionally censor at discontinuation (last days_supply end + a pre-specified grace period) or switch, and apply inverse-probability-of-censoring weights; for the sustained "remain on class" strategy, clone-censor-weight. Sensitivity analyses: washout length, grace period, negative-control outcomes, and an E-value for residual confounding.

Worked example

Scenario

A researcher wants to know whether adults with type 2 diabetes who start an SGLT2 inhibitor have fewer heart attacks over three years than those who start a DPP-4 inhibitor. Patient 2041 fills her first SGLT2 inhibitor prescription on 2023-03-01 after 365 days of uninterrupted insurance enrollment with no prior fill of either drug class. In the properly emulated trial, that fill date is time zero: eligibility is confirmed on that day, the treatment arm is assigned on that day, and follow-up begins on that day. In a naive analysis, the researcher might instead start the clock at the diagnosis date (2022-08-15) and only classify her as treated when the fill occurs six and a half months later, which would silently gift the treated arm 197 guaranteed event-free days.

Dataset

Key dates for patient 2041 in a commercial claims database, showing both the naive start and the aligned emulation start.

person_ideventdatedays_since_diagnosis
2041T2D diagnosis (first of 2)2022-08-15
2041T2D diagnosis (second)2022-10-0248
2041365-day washout window opens (no SGLT2/DPP-4 fills)2022-03-01-167
2041First SGLT2i fill = TIME ZERO (aligned emulation)2023-03-01197
2041Naive cohort entry (diagnosis date)2022-08-15
2041Naive treatment classification date (= first fill)2023-03-01197

Steps

  • Naive approach: the researcher anchors the study clock at the T2D diagnosis date (2022-08-15) and retrospectively labels patient 2041 as 'treated' once her SGLT2i fill occurs on 2023-03-01.

  • That creates 197 days (Aug 15, 2022 to Mar 1, 2023) where she is counted in the treated arm but could not yet have been treated — she had to survive those days without a heart attack just to qualify as treated.

  • Those 197 days are immortal time: the treated arm looks healthier simply because untreated patients who had a heart attack before the fill could never enter the treated group.

  • Emulation fix: set time zero to the first qualifying fill date (2023-03-01). Eligibility (365-day washout, two T2D diagnoses, continuous enrollment) is confirmed as of that same date. Follow-up also starts on that same date.

  • Because eligibility, assignment, and follow-up all begin on 2023-03-01, there are zero immortal days: no event-free time is pre-loaded into either arm.

  • Both the SGLT2i arm (patient 2041) and the DPP-4i arm start follow-up at their own individual time zeros, which is the first qualifying fill of whichever drug class they actually initiated.

Result

Aligned emulation: 0 immortal days for patient 2041; follow-up begins 2023-03-01 and runs up to 3 years or first MACE event, whichever comes first. Naive analysis: 197 days of immortal time silently credited to the treated arm before follow-up even started, biasing the treated group toward better outcomes.

Timeline Spec

Title

Time zero alignment for patient 2041 — SGLT2i initiation emulating a target trial

Window
Start

2022-08-15

End

2026-03-01

Label

Observation window: diagnosis through 3-year follow-up

Events
  • Label

    T2D diagnosis #1

    Start

    2022-08-15

    Length Days

    1

    Quantity

    eligibility criterion

  • Label

    365-day washout (no SGLT2/DPP-4 fills)

    Start

    2022-03-01

    Length Days

    365

    Quantity

    365-day drug-free lookback

  • Label

    First SGLT2i fill — TIME ZERO

    Start

    2023-03-01

    Length Days

    90

    Quantity

    90-day supply; eligibility + assignment + follow-up start here

Spans
  • Kind

    unexposed

    Start

    2022-08-15

    End

    2023-02-28

    Label

    197-day immortal time in naive analysis (event-free days silently credited to treated arm)

  • Kind

    followup

    Start

    2023-03-01

    End

    2026-03-01

    Label

    3-year follow-up (ITT emulation, aligned time zero)

Result
Label

Time zero = 2023-03-01 (first SGLT2i fill). Immortal days in aligned emulation = 0. Immortal days in naive analysis = 197.

Caption

Patient 2041 timeline showing the 197-day immortal period that the naive analysis silently adds to the treated arm (shaded), versus the aligned target-trial emulation where eligibility, treatment assignment, and follow-up all start together on the date of the first fill.

Alt Text

A horizontal timeline from August 2022 to March 2026 for one patient. A shaded band from the T2D diagnosis date to the first SGLT2i fill marks 197 days of immortal time present in the naive analysis. A vertical line at the first fill date (March 1 2023) marks the aligned time zero, where eligibility, assignment, and follow-up all coincide in the emulated trial.

Runnable example

python implementation

Protocol-to-emulation cohort builder for a two-strategy target trial (ITT contrast). This is the design layer, not the estimator: it walks the seven protocol components and emits one row per eligible initiator at time zero, ready for propensity-score...

import pandas as pd

WASHOUT_DAYS = 365  # drug-free + continuous-enrollment lookback that defines incident users and fixes time zero

def emulate_target_trial(rx: pd.DataFrame, enroll: pd.DataFrame, elig: pd.DataFrame) -> pd.DataFrame:
    rx = rx.sort_values(["person_id", "fill_date"])

    # (2) Treatment strategies + (4) time zero: first fill of EITHER comparator class is the candidate index.
    study = rx[rx["drug_class"].isin(["SGLT2", "DPP4"])]
    idx = (study.groupby("person_id").first().reset_index()
                .rename(columns={"fill_date": "index_date", "drug_class": "arm"}))

    # New-user check (belt-and-suspenders): no fill of either class in the washout window before time zero.
    # NOTE: because index_date is the FIRST observed fill, no in-data fill can predate it, so this filter is
    # vacuous on its own and `prevalent` is empty by construction. The actual new-user guarantee comes from the
    # continuous-enrollment-across-the-full-washout check below ((1) `covers`): requiring FFS-observable
    # enrollment for the entire [index-WASHOUT, index] window means any prior fill WOULD have been observed, so
    # the absence of one is a true drug-free period rather than missingness. This filter only catches the edge
    # case where the input `rx` already carries fills earlier than the per-person first fill in `study`.
    prior = study.merge(idx[["person_id", "index_date"]], on="person_id")
    prevalent = prior[(prior["fill_date"] < prior["index_date"]) &
                      (prior["fill_date"] >= prior["index_date"] - pd.Timedelta(days=WASHOUT_DAYS))]
    idx = idx[~idx["person_id"].isin(prevalent["person_id"])].copy()

    # (1) Eligibility assessed AT time zero only: continuous FFS-observable enrollment across the full washout,
    #     plus the clinical criteria (>=2 T2D dx, CKD-3 marker on/before index). MA-only person-time excluded.
    #     This enrollment-coverage check is what enforces incident (new-user) status, not the filter above.
    e = enroll.merge(idx[["person_id", "index_date"]], on="person_id")
    e["covers"] = ((e["enroll_start"] <= e["index_date"] - pd.Timedelta(days=WASHOUT_DAYS)) &
                   (e["enroll_end"]   >= e["index_date"]) & (~e["ma_only"]))
    observable = set(e.loc[e["covers"], "person_id"])

    idx = idx.merge(elig, on="person_id", how="left")
    clinically_eligible = (idx["n_t2d_dx"] >= 2) & (idx["ckd3_date"] <= idx["index_date"])
    cohort = idx[idx["person_id"].isin(observable) & clinically_eligible].copy()

    # Covariate/PS window = [time zero - washout, time zero]. Follow-up (5)-(7) and censoring applied identically
    # to both arms downstream; ITT follows the assigned arm regardless of later switching.
    cohort["baseline_start"] = cohort["index_date"] - pd.Timedelta(days=WASHOUT_DAYS)
    return cohort[["person_id", "arm", "index_date", "baseline_start"]]