Pragmatic Trial
A randomized trial designed to measure the effectiveness of an intervention under usual-care conditions in a broadly eligible population, typically embedded in routine-care data (EHR, registry, or claims) rather than a dedicated research infrastructure.
On this page
A pragmatic trial is a randomized experiment designed to answer a simple question: does this treatment actually work for real patients in real clinics? Unlike a tightly controlled lab-style trial that recruits only ideal patients and enforces every dose, a pragmatic trial enrolls the broad, messy population that shows up for care, lets clinicians deliver treatment the way they normally would, and tracks outcomes using records that already exist, such as electronic health records or insurance claims. It keeps the one thing that makes experiments trustworthy, namely random assignment, while deliberately relaxing everything else so the answer reflects what happens in the world, not what happens under perfect conditions.
A pragmatic clinical trial (PCT) preserves randomization — the one design feature observational RWE cannot buy — while deliberately relaxing every other feature of the classic explanatory trial so the result generalizes to ordinary practice.
Eligibility is broad (few exclusions for comorbidity, age, or polypharmacy), the intervention is delivered with usual flexibility by usual clinicians in usual settings, adherence is not artificially enforced, follow-up uses routine-care touchpoints, and outcomes are ascertained from data that already exist (EHR, disease registries, dispensing records, claims, vital records).
The canonical modern examples — the Salford Lung Study (linked primary-care EHR + community-pharmacy dispensing), TASTE (the SWEDEHEART registry-based randomized trial), and ADAPTABLE (PCORnet EHR-embedded aspirin-dose trial) — randomize within a real-world data substrate, which is precisely why pragmatic trials sit inside the RWE catalog rather than beside it.
Core conceptual distinction
The defining contrast is pragmatic vs explanatory (Schwartz & Lellouch, 1967), and it is a continuum, not a binary — the central thesis of the PRECIS-2 tool, which scores a design from 1 (very explanatory) to 5 (very pragmatic) on nine domains: eligibility, recruitment, setting, organization, flexibility of the experimental intervention's delivery, flexibility of adherence, follow-up intensity, primary outcome, and primary analysis.
An explanatory trial maximizes internal validity and asks can this work under ideal conditions (efficacy); a pragmatic trial maximizes external validity and asks does this work in routine care (effectiveness).
The estimand differs accordingly: a PCT targets the effectiveness of a treatment strategy under usual-care conditions, analyzed intention-to-treat in a broadly eligible population, with non-adherence and treatment switching treated as part of the real-world effect rather than nuisance to be censored away.
This is the same effectiveness estimand a target-trial emulation tries to recover from observational data — but the PCT gets it with actual randomization, so confounding (including unmeasured confounding) is handled by design rather than by adjustment, instrumental variables, or sensitivity analysis.
What randomization does not buy is freedom from the operational biases of routine-data outcome ascertainment, blinding-related performance bias (most PCTs are open-label), or the loss of mechanistic interpretability that tight explanatory control provides.
Pros, cons, and trade-offs
(specific & comparative).
- vs the explanatory RCT: A PCT trades some internal validity and precision for direct generalizability and far lower cost per patient (routine-data outcomes eliminate dedicated CRFs and study visits). Cost: open-label delivery invites performance and ascertainment bias, broad eligibility plus real-world non-adherence shrinks the effect size toward the null and demands a larger sample, and "soft" or clinician-judged outcomes captured in routine data are more vulnerable to detection bias than blinded adjudicated endpoints. Prefer the PCT when efficacy is already established and the decision-relevant question is real-world effectiveness, value, or comparative benefit among active options.
- vs target-trial emulation (observational): The PCT randomizes, so it is the gold standard for the same effectiveness estimand the emulation approximates; it removes confounding by indication, healthy-user bias, and immortal time by design. Cost: it requires prospective consent/randomization infrastructure, takes years, and cannot be done where equipoise or ethics forbid randomization. Prefer emulation when randomization is infeasible, too slow, or unethical, and treat the PCT as the benchmark the emulation should reproduce.
- vs single-arm trial with an external control: A PCT has a concurrent randomized comparator, eliminating the comparability threats that dominate external-control studies. Cost: it needs enough eligible patients to randomize a control arm, which external-control designs avoid in ultra-rare diseases. Prefer external controls only when a randomized concurrent arm is genuinely impossible.
- registry-based / cluster-randomized variants: Embedding randomization in a registry (TASTE) or randomizing sites/clinics rather than patients (cluster-PCT) lowers burden and enables system-level interventions, at the price of registry-capture gaps, clustering-induced loss of power (the design effect), and identification/recruitment bias when sites — not blinded individuals — know their allocation.
When NOT to use — and when it is actively misleading or dangerous
(decision rules).
- Efficacy and mechanism are still unknown. A pragmatic effectiveness trial run before efficacy is established conflates "the drug doesn't work" with "it wasn't taken correctly" — the diluted ITT effect under poor adherence can hide a real biological effect and kill a useful therapy, or conversely mask a safety signal.
- The primary outcome cannot be captured well from routine data. If the endpoint requires standardized imaging, central adjudication, or scheduled biomarker draws that routine care does not perform, claiming "pragmatic" ascertainment introduces differential, open-label detection bias — dangerous when the arm influences how aggressively the outcome is looked for.
- Blinding is essential and impossible pragmatically. For subjective or clinician-determined outcomes with an unblinded intervention, the pragmatic frame can manufacture a spurious effect; this is where pragmatic ascertainment is actively misleading, not merely imprecise.
- No equipoise / ethics forbid randomization, or the intervention is unsafe to deliver under usual flexibility. Then a PCT is infeasible and an observational target-trial emulation or external-control design is the honest alternative.
- Beware "pragmatic" as a label of convenience. A trial that is explanatory on eligibility and analysis but calls itself pragmatic to borrow generalizability claims fails PRECIS-2 scrutiny; reviewers will (correctly) demand the nine-domain wheel.
Data-source operational depth
The pragmatic promise lives or dies on the routine-data substrate used for eligibility screening and outcome capture, and each substrate has distinct failure modes.
- Claims (FFS or commercial): Excellent for complete dispensing, procedures, and encounters within an enrolled, fee-for-service window; ideal for randomizing among already-marketed therapies and ascertaining hospitalization/procedure/mortality-proxy outcomes. Failure modes: Medicare Advantage and capitated person-time silently drop FFS claims, so a patient who switches to MA mid-trial appears to have zero events — restrict outcome person-time to observable FFS+Part D coverage and treat MA enrollment as administrative censoring, not as an event-free interval. Adjudication/ascertainment lag (claims mature over 3–6 months) means interim outcome counts undercount recent events; lock data only after a run-out window. Diagnosis-code outcomes need a validated algorithm with a known PPV.
- EHR-embedded (e.g., Salford Lung, ADAPTABLE/PCORnet): Rich on labs, vitals, problem lists, and clinician notes for broad eligibility screening and severity capture; supports point-of-care randomization. Failure mode: visit-driven, leaky capture — a patient who seeks care outside the network is differentially unobserved, and if leaving correlates with the outcome (or with the arm) the effect is biased. Salford addressed this by linking community-pharmacy dispensing and hospital records to its primary-care EHR so events outside the index practice were still caught; without such linkage, define the observation window explicitly and treat out-of-network loss as potentially informative.
- Registry-based randomized trial (e.g., TASTE / SWEDEHEART): Near-complete enrollment of the target population, adjudicated clinical outcomes, and randomization folded into an existing data-entry workflow at trivial marginal cost. Failure mode: the registry captures only what it was built to capture — off-protocol medication switches, outcomes treated at non-participating hospitals, and out-of-country events fall outside it, so concomitant-therapy contamination and some events go unrecorded; link to national dispensing and death registries to close the gap.
- Linked claims–EHR–registry–vital records: The strongest substrate (EHR severity + claims completeness + registry adjudication + reliable mortality), but linkage selection (only the linkable subset randomizes/contributes) and date-discrepancy reconciliation across order, dispense, and service dates must be resolved before randomization-date and outcome-window assignment.
Worked claims/EHR example
Question: among adults with COPD in routine primary care, does once-daily fluticasone furoate–vilanterol reduce moderate-or-severe exacerbations vs continuing usual maintenance therapy, as delivered in practice (the Salford Lung effectiveness estimand)?
- Pragmatic eligibility (broad, few exclusions): age ≥40, ≥1 recorded COPD diagnosis in the EHR problem list, ≥1 maintenance-inhaler dispensing in the prior 12 months, and continuous, FFS-observable medical+pharmacy coverage for a 365-day baseline window (so prior-therapy and comorbidity history is real, not missing); do not exclude for common comorbidity, polypharmacy, or mild-to-moderate renal/hepatic impairment, which an explanatory trial would.
- Randomization unit & assignment: randomize the patient 1:1 at the point of care (EHR flag at the index encounter), record `index_date` = randomization date; for a cluster variant, randomize the practice and stamp every enrolled patient with the site allocation.
- Real-world delivery: no enforced adherence — the intervention arm is prescribed the study inhaler and then followed exactly as routine patients are (refills via `fill_date` + `days_supply`, switches and discontinuations left to occur).
- Outcome ascertainment from routine data: a moderate exacerbation = an outpatient claim with a COPD-exacerbation diagnosis plus a dispensing of an oral corticosteroid and/or antibiotic within a 14-day window; a severe exacerbation = an inpatient/ED claim with a primary COPD-exacerbation code — both via a validated algorithm with documented PPV.
- Person-time rules: follow from `index_date` to first qualifying exacerbation; administratively censor at MA enrollment, disenrollment, death, or data-end, and exclude MA-only spans from the at-risk denominator because their claims are unobservable (an event there would be silently missed).
- Analysis: intention-to-treat by randomized arm, counting events under as-prescribed routine care; report the effectiveness rate ratio with a pre-specified run-out window so claims-maturation lag does not undercount late events, and a per-protocol/on-treatment sensitivity analysis with inverse-probability-of-censoring weights to bracket the contamination from real-world switching.
Decision diagram
flowchart TD
Pop[Broad real-world population<br/>few exclusions: comorbidity, age, polypharmacy allowed] --> Elig[Eligibility screened from routine data<br/>EHR problem list / registry / claims]
Elig --> Rand{Randomize<br/>patient or cluster/site}
Rand -->|Arm A| Usual[Intervention delivered under usual care<br/>no enforced adherence, usual clinicians]
Rand -->|Arm B| Comp[Comparator / usual maintenance therapy]
Usual --> Out[Outcome ascertained from routine data<br/>claims / EHR / registry / death index]
Comp --> Out
Out --> ITT[Intention-to-treat effectiveness estimand<br/>effect under usual-care conditions]flowchart LR
subgraph EXPLANATORY[Explanatory pole - efficacy]
E1[Narrow eligibility]
E2[Protocolized delivery]
E3[Enforced adherence]
E4[Intensive scheduled follow-up]
E5[Blinded adjudicated outcome]
end
subgraph PRAGMATIC[Pragmatic pole - effectiveness]
P1[Broad eligibility]
P2[Usual-care delivery]
P3[Real-world adherence]
P4[Routine-care follow-up]
P5[Routine-data outcome]
end
E1 -. PRECIS-2 continuum .-> P1
E2 -. eligibility/setting/organization .-> P2
E3 -. flexibility of adherence .-> P3
E4 -. follow-up intensity .-> P4
E5 -. primary outcome/analysis .-> P5Worked example
Scenario
Imagine a study asking: among adults with a common lung disease called COPD, does a new combination inhaler reduce flare-ups compared to whatever maintenance inhaler patients are already using? The team wants to know what happens in routine primary-care clinics, not in a specialized research center. Below is a side-by-side comparison of how a pragmatic trial and a classic explanatory trial would each be designed to answer that question.
Dataset
Pragmatic trial vs. explanatory trial across five design dimensions. Each row is a design choice; the contrast shows why the two trials answer different questions.
| Design dimension | Explanatory trial (efficacy) | Pragmatic trial (effectiveness) |
|---|---|---|
| Population | Narrow: age 40-65, no other lung disease, no other medications, non-smoker for 5+ years | Broad: any adult with a recorded COPD diagnosis, common co-diseases allowed, smokers included |
| Setting | Specialist respiratory clinics at academic medical centers | Any primary-care practice that already cares for COPD patients |
| How treatment is delivered | Fixed dose, fixed schedule, monitored by study nurse at every visit | Clinician prescribes and adjusts as they see fit; no study-mandated visits |
| Comparator | Placebo inhaler (identical-looking dummy device) | Usual maintenance therapy the patient was already taking |
| How outcomes are measured | Lung-function tests performed on a schedule by trained technicians | Exacerbation events pulled from routine EHR records and pharmacy dispensing data |
Steps
Result
A pragmatic trial answers: does this treatment produce better outcomes than the alternative patients would actually receive, for the real population of patients who have this condition, delivered the way clinicians would actually deliver it? That is an effectiveness answer. An explanatory trial answers a narrower efficacy question: can this treatment outperform placebo in an ideal population under ideal conditions?
Trade-offs
Runnable example
Pragmatic-trial cohort/eligibility construction and routine-data outcome ascertainment (NOT effect estimation). Required inputs (already cleaned and de-duplicated): dx : diagnoses -> person_id, dx_date (datetime), dx_code, setting in {'OUTPATIENT','INPATIENT','ED'} rx : pharmacy fills -> person_id, fill_date...
import pandas as pd
import numpy as np
BASELINE_DAYS = 365 # observable-coverage lookback so history is real, not missing
OCS_ABX_WINDOW = 14 # days: outpatient COPD dx + steroid/antibiotic = moderate exacerbation
COPD_DX = {"J44.0", "J44.1", "J44.9"}
EXAC_OCS_ABX = {"OCS", "ANTIBIOTIC"} # drug_class values flagging an exacerbation treatment
def screen_eligibility(dx, rx, enroll, arms):
"""arms: DataFrame[person_id, index_date (randomization date), arm] from the registry/EHR/RNG."""
elig = arms.merge(enroll, on="person_id", how="left")
# Pragmatic: require only observable FFS coverage spanning the baseline window through randomization.
elig["covered"] = (
(elig["enroll_start"] <= elig["index_date"] - pd.Timedelta(days=BASELINE_DAYS))
& (elig["enroll_end"] >= elig["index_date"])
& (~elig["ma_only"])
)
# Require a recorded COPD diagnosis and >=1 maintenance fill in the baseline window (broad inclusion).
base_dx = dx.merge(arms[["person_id", "index_date"]], on="person_id")
has_copd = base_dx[
base_dx["dx_code"].isin(COPD_DX)
& (base_dx["dx_date"] <= base_dx["index_date"])
& (base_dx["dx_date"] >= base_dx["index_date"] - pd.Timedelta(days=BASELINE_DAYS))
]["person_id"].unique()
keep = elig.loc[elig["covered"] & elig["person_id"].isin(has_copd),
["person_id", "index_date", "arm"]]
return keep.drop_duplicates("person_id")
def first_exacerbation(cohort, dx, rx, enroll):
"""First moderate (outpatient COPD dx + OCS/abx within 14d) OR severe (inpatient/ED COPD dx) event.
Person-time during MA-only spans is unobservable -> such events are dropped and the span censored upstream."""
d = dx.merge(cohort[["person_id", "index_date"]], on="person_id")
d = d[(d["dx_code"].isin(COPD_DX)) & (d["dx_date"] >= d["index_date"])]
severe = d[d["setting"].isin(["INPATIENT", "ED"])][["person_id", "dx_date"]].assign(severity="severe")
out_copd = d[d["setting"] == "OUTPATIENT"][["person_id", "dx_date"]]
exac_rx = rx[rx["drug_class"].isin(EXAC_OCS_ABX)][["person_id", "fill_date"]]
m = out_copd.merge(exac_rx, on="person_id")
m = m[(m["fill_date"] >= m["dx_date"])
& (m["fill_date"] <= m["dx_date"] + pd.Timedelta(days=OCS_ABX_WINDOW))]
moderate = m[["person_id", "dx_date"]].drop_duplicates().assign(severity="moderate")
events = pd.concat([severe, moderate], ignore_index=True)
first = (events.sort_values(["person_id", "dx_date"])
.groupby("person_id").first().reset_index()
.rename(columns={"dx_date": "event_date"}))
return cohort.merge(first, on="person_id", how="left") # event_date NaT => no event in observed timePragmatic-trial eligibility screening + routine-data outcome ascertainment with data.table (mirrors the Python version). Inputs: dx : person_id, dx_date (Date), dx_code, setting in {'OUTPATIENT','INPATIENT','ED'} rx : person_id, fill_date (Date), drug_class, days_supply enroll : person_id, enroll_start, enroll_end,...
library(data.table)
BASELINE_DAYS <- 365L
OCS_ABX_WINDOW <- 14L
COPD_DX <- c("J44.0", "J44.1", "J44.9")
screen_eligibility <- function(dx, rx, enroll, arms) {
setDT(dx); setDT(enroll); setDT(arms)
e <- merge(arms, enroll, by = "person_id", all.x = TRUE)
# Pragmatic: only require observable FFS coverage across the baseline window through randomization.
e[, covered := enroll_start <= index_date - BASELINE_DAYS &
enroll_end >= index_date & !ma_only]
bdx <- merge(dx, arms[, .(person_id, index_date)], by = "person_id")
has_copd <- bdx[dx_code %chin% COPD_DX &
dx_date <= index_date &
dx_date >= index_date - BASELINE_DAYS, unique(person_id)]
keep <- e[covered == TRUE & person_id %chin% has_copd,
.(person_id, index_date, arm)]
unique(keep, by = "person_id")
}
first_exacerbation <- function(cohort, dx, rx, enroll) {
setDT(cohort); setDT(dx); setDT(rx)
d <- merge(dx, cohort[, .(person_id, index_date)], by = "person_id")
d <- d[dx_code %chin% COPD_DX & dx_date >= index_date]
severe <- d[setting %chin% c("INPATIENT", "ED"),
.(person_id, event_date = dx_date, severity = "severe")]
out_copd <- d[setting == "OUTPATIENT", .(person_id, dx_date)]
exac_rx <- rx[drug_class %chin% c("OCS", "ANTIBIOTIC"), .(person_id, fill_date)]
m <- merge(out_copd, exac_rx, by = "person_id", allow.cartesian = TRUE)
m <- m[fill_date >= dx_date & fill_date <= dx_date + OCS_ABX_WINDOW]
moderate <- unique(m[, .(person_id, event_date = dx_date)])[, severity := "moderate"]
events <- rbind(severe, moderate)
setorder(events, person_id, event_date)
first <- events[, .SD[1L], by = person_id]
merge(cohort, first, by = "person_id", all.x = TRUE) # event_date NA => no observed event
}Pragmatic-trial eligibility screening + routine-data outcome ascertainment in SAS (PROC SQL cohort build). Required input datasets (post data-management): work.dx : person_id, dx_date, dx_code, setting ('OUTPATIENT'/'INPATIENT'/'ED') work.rx : person_id, fill_date, drug_class, days_supply work.enroll : person_id,...
%let baseline = 365; /* observable-coverage lookback */
%let win = 14; /* OCS/antibiotic window for a moderate exacerbation */
/* ----- Step 1: broad pragmatic eligibility -------------------------------- */
proc sql;
create table cohort as
select a.person_id, a.index_date format=date9., a.arm
from work.arms a
where /* observable FFS coverage spanning baseline through randomization */
exists (select 1 from work.enroll e
where e.person_id = a.person_id
and e.ma_only = 0
and e.enroll_start <= a.index_date - &baseline
and e.enroll_end >= a.index_date)
and /* >=1 recorded COPD diagnosis in the baseline window (few other exclusions) */
exists (select 1 from work.dx d
where d.person_id = a.person_id
and d.dx_code in ('J44.0','J44.1','J44.9')
and d.dx_date <= a.index_date
and d.dx_date >= a.index_date - &baseline);
quit;
/* ----- Step 2: severe exacerbations (inpatient/ED COPD dx after randomization) --- */
proc sql;
create table severe as
select c.person_id, d.dx_date as event_date format=date9., 'severe' as severity length=8
from cohort c
join work.dx d
on d.person_id = c.person_id
and d.dx_code in ('J44.0','J44.1','J44.9')
and d.setting in ('INPATIENT','ED')
and d.dx_date >= c.index_date;
quit;
/* ----- Step 2b: moderate exacerbations (outpatient COPD dx + OCS/abx within window) --- */
proc sql;
create table moderate as
select distinct c.person_id, d.dx_date as event_date format=date9., 'moderate' as severity length=8
from cohort c
join work.dx d
on d.person_id = c.person_id and d.dx_code in ('J44.0','J44.1','J44.9')
and d.setting = 'OUTPATIENT' and d.dx_date >= c.index_date
join work.rx r
on r.person_id = c.person_id and r.drug_class in ('OCS','ANTIBIOTIC')
and r.fill_date between d.dx_date and d.dx_date + &win;
quit;
/* ----- Step 3: first qualifying event per person -------------------------- */
proc sql;
create table first_event as
select person_id, min(event_date) as event_date format=date9.
from (select * from severe union all select * from moderate)
group by person_id;
quit;
proc sql; /* left join so persons with no observed event keep a missing event_date */
create table analysis as
select c.*, f.event_date
from cohort c left join first_event f on c.person_id = f.person_id;
quit;Citations
- [1]Ford I, Norrie J. Pragmatic trials. New England Journal of Medicine. 2016;375(5):454-463.
- [2]Schwartz D, Lellouch J. Explanatory and pragmatic attitudes in therapeutical trials. Journal of Chronic Diseases. 1967;20(8):637-648.
- [3]Loudon K, Treweek S, Sullivan F, Donnan P, Thorpe KE, Zwarenstein M. The PRECIS-2 tool: designing trials that are fit for purpose. BMJ. 2015;350:h2147.
- [4]Zwarenstein M, Treweek S, Gagnier JJ, et al. Improving the reporting of pragmatic trials: an extension of the CONSORT statement. BMJ. 2008;337:a2390.