Inpatient Bridging of Drug Exposure
A pre-specified rule that decides how to treat days during a hospital stay when outpatient pharmacy fills are absent or suspended, when constructing exposure episodes and adherence/persistence measures from claims or linked data.
On this page
When a patient is hospitalized, the hospital supplies their medication directly — no prescription gets filled at a pharmacy, so no record of those days shows up in outpatient claims data. Naively stitching prescription fills together makes the hospital stay look like a gap in drug coverage, even though the patient never actually stopped taking the medication. Inpatient bridging is a pre-specified rule that says: during a confirmed hospital stay, treat the patient as still covered by their chronic medication rather than calling those days a gap. Without this rule, a patient who was faithfully taking a heart medication through a two-week admission can be mislabeled 'non-adherent' purely because the data source cannot see inside the hospital.
Inpatient bridging
is the explicit, protocol-level decision about what an exposure series should assume during the days a patient is hospitalized. In outpatient pharmacy claims, exposure is reconstructed by stitching together fills (`fill_date` + `days_supply`). During an inpatient stay the patient typically receives medication from the hospital formulary, so there is no outpatient fill — and in claims-only data the inpatient drug is bundled into the DRG/facility payment and is therefore invisible.
The series shows an apparent gap that is an artifact of where the drug was sourced, not evidence the patient stopped therapy. How that gap is handled changes denominators, exposure time, gap counts, and every downstream measure (PDC, MPR, persistence, time-varying exposure). This is an `Exposure_Definition` problem, not an estimation problem: the choice is made in the cohort/episode build, before any model.
Core conceptual distinction
There are three canonical bridging policies, and they are mutually exclusive choices that must be named in the protocol: 1. Carry-over (assume continuation): treat inpatient days as covered/exposed — bridge across the stay as if the drug continued. Rationale: an inpatient who was on chronic therapy is overwhelmingly likely to have it continued in hospital. This is the most common default for chronic maintenance drugs. 2.
Censor (remove inpatient days from the denominator)
exclude hospitalized days from the observation window entirely, so they count as neither covered nor uncovered. This is the PQA / CMS Star Ratings convention for adherence PDC: inpatient and skilled-nursing days are removed from the denominator and any overlapping supply is "pushed back," because the member's outpatient adherence cannot be observed during institutional stays. 3. Treat as gap / discontinuation: count inpatient days as uncovered (a true gap), or end the exposure episode at admission.
Appropriate only when the drug is genuinely not expected to continue (e.g., a therapy held for the procedure, a discontinued agent). The estimand-adjacent point: these three policies are not nuances — for a patient with frequent or long admissions they produce materially different PDC and persistence values, and the "right" choice depends on the clinical expectation for that specific drug during that specific kind of stay.
Pros, cons, and trade-offs
(vs the named alternatives):
- Carry-over vs censor: Carry-over is simple and matches the clinical reality for chronic drugs, but it manufactures coverage you did not observe and can mask true non-adherence around discharge. Censoring (PQA-style) is the most defensible when the question is observable outpatient adherence and is required for Star Ratings comparability, but it shrinks the denominator, can inflate PDC for frequently hospitalized (sicker) patients, and complicates person-time accounting. Prefer carry-over for chronic maintenance therapy in an etiologic study; prefer censor for regulated quality measurement and when inpatient supply is unknowable.
- Carry-over vs treat-as-gap: Treat-as-gap is correct only for drugs plausibly held during the stay; applied to a chronic drug it invents discontinuations and biases persistence downward. Prefer treat-as-gap only with a clinical rationale, ideally validated against linked MAR/eMAR data.
- vs ignoring the issue (naive stitching): Doing nothing silently applies whatever the default `days_supply` arithmetic produces — usually a phantom gap. That is the worst option because the policy is implicit and undocumented. Any of the three explicit policies beats an unstated one.
When NOT to use — and when it is actively misleading or dangerous
Bridging is unnecessary when admissions are rare and short relative to the supply and outcome window (the choice cannot move the estimate). It becomes actively dangerous in three situations. (1) Asymmetric application — bridging one arm (or only the study drug) but not the comparator manufactures immortal time and covered person-time for one side, biasing the comparative estimate; the rule must be applied identically to both arms (see immortal-time-bias-handling).
(2) Differential hospitalization by arm — if the sicker arm is hospitalized more, a carry-over policy donates more phantom coverage to that arm, while a censoring policy removes more of its observable time; either way the policy choice becomes outcome-dependent, so a sensitivity analysis across all three policies is not optional. (3) Treating-as-gap a drug that was actually continued in hospital — fabricates discontinuations, corrupts persistence, and (in claims-only data, where you cannot see the inpatient administration) is unfalsifiable without linkage.
Data-source operational depth
- Claims (FFS): Identify inpatient stays from institutional/facility claims (revenue center codes, place-of-service, DRG, admit/discharge dates). The inpatient drug is bundled into the facility payment and never appears as an NDC, so you must infer coverage from the stay dates plus the surrounding outpatient fills. Reconstruct admission and discharge from the medical claim, then apply the chosen policy to `[admit_date, discharge_date]`. Failure mode: over-the-counter or sample inpatient continuation is invisible; same-day discharge fills and discharge-prescription "med rec" fills can double-count if not deduped.
- Claims (Medicare Advantage / capitated): MA encounter data are notoriously incomplete and lag; an MA-only person may have neither the institutional claim nor reliable Part D fills, so "no fill during a window" can be pure missingness rather than a real gap or a real stay. Restrict to FFS Parts A/B/D person-time, or flag MA-only spans and exclude them from the denominator — do not let MA missingness masquerade as non-adherence.
- EHR: The inpatient administration is visible in the MAR/eMAR and inpatient order records, so bridging can be evidence-based rather than assumed — but only if the hospital is inside the EHR network. External-hospital stays leak out of the system and reappear as the same phantom gap as in claims; visit-driven capture means the patient who is admitted elsewhere is differentially unobserved.
- Registry: Usually weak for both fills and inpatient drug administration; use registry admission/severity fields to flag stays, but link to claims (fills) and to facility claims (stay dates) to actually operationalize the rule.
- Linked claims–EHR: The ideal substrate — facility claims give reliable stay dates and the linked inpatient MAR confirms whether the specific drug was continued, letting you choose carry-over vs treat-as-gap per stay on evidence rather than assumption. Cost: only the linkable subset is covered, and admit/fill/service date discrepancies must be reconciled before bridging.
Worked claims example
A patient on a chronic statin fills a 30-day supply on 2024-01-01 (covers 2024-01-01 → 2024-01-30). A facility claim shows an inpatient stay 2024-01-11 → 2024-01-20 (10 days). The next outpatient fill (30 days) is 2024-02-05. The follow-up window is the 35 days 2024-01-01 → 2024-02-04. Compute PDC under each policy:
- Carry-over: the in-hospital days are assumed covered. Covered days = Jan 1–30 (30 from the first fill, with the admission spanned) → no gap is recognized during the stay; the only uncovered days are Jan 31 → Feb 4 (5 days). PDC = 30 / 35 ≈ 0.857.
- Censor (PQA): remove the 10 inpatient days from the denominator (Jan 11–20). Denominator = 35 − 10 = 25 days; covered observable days = Jan 1–10 (10) + Jan 21–30 (10) = 20. PDC = 20 / 25 = 0.800. (PQA additionally "pushes back" supply that overlapped the removed days, which can recover days near discharge; the directional point — a different denominator — holds.)
- Treat-as-gap: the 10 inpatient days are uncovered. Covered = Jan 1–10 (10) + Jan 21–30 (10) = 20 over a 35-day denominator → PDC = 20 / 35 ≈ 0.571. Same patient, same fills: PDC ranges 0.571 → 0.857 — straddling the 0.80 quality-measure threshold — purely from the bridging rule. That single decision can flip a patient from "non-adherent" to "adherent," which is why the policy must be pre-specified, applied identically across arms, and stress-tested in sensitivity analysis.
Decision diagram
flowchart TD
Stay[Hospital stay detected<br/>facility claim: admit_date..discharge_date] --> Q1{Is the drug expected<br/>to continue in hospital?}
Q1 -->|Yes, chronic maintenance| CO[Carry-over:<br/>inpatient days = covered]
Q1 -->|Unknown / claims-only<br/>cannot observe| Q2{Is the estimand<br/>observable outpatient<br/>adherence / PQA measure?}
Q1 -->|No, drug held / stopped| GAP[Treat as gap:<br/>inpatient days = uncovered]
Q2 -->|Yes| CEN[Censor:<br/>remove inpatient days<br/>from denominator]
Q2 -->|No, etiologic continuation| CO
CO --> SENS[Apply identically to BOTH arms<br/>+ sensitivity analysis across all 3 policies]
CEN --> SENS
GAP --> SENSgantt title One patient, one 30-day fill spanning a 10-day admission (Jan 1 - Feb 4 window) dateFormat YYYY-MM-DD axisFormat %d-%b section Events 30-day fill (covers Jan 1 - Jan 30) :done, fill, 2024-01-01, 30d Inpatient stay (no outpatient fill) :crit, stay, 2024-01-11, 10d section Carry-over (PDC 0.857) Covered incl. in-hospital days :active, co, 2024-01-01, 30d section Censor / PQA (PDC 0.800) Covered, inpatient days removed from denom :active, ce, 2024-01-01, 10d section Treat-as-gap (PDC 0.571) Covered, inpatient days uncovered :active, ga1, 2024-01-01, 10d Covered after discharge :active, ga2, 2024-01-21, 10d
Worked example
Scenario
Maria, age 68, has been taking a daily statin for high cholesterol for years. We are studying her medication coverage over a 60-day window from January 2 through March 1, 2024. She fills a 14-day supply on January 2, then is admitted to the hospital on January 10 and discharged on January 29 (a 20-day stay). The hospital keeps her on the statin the entire time, but no outpatient pharmacy claim is generated — the drug comes from the hospital's own supply. Her next outpatient fill is a 30-day supply on February 1. We want to compute how many days she actually had the drug during the 60-day window, and we will compare the naive (no-bridging) result to the carry-over-bridging result.
Dataset
Raw outpatient pharmacy fills — these are the only pill records visible without bridging. The hospital stay appears only in a separate facility claim (bottom table).
| person_id | fill_date | drug | days_supply |
|---|---|---|---|
| 2001 | 2024-01-02 | atorvastatin | 14 |
| 2001 | 2024-02-01 | atorvastatin | 30 |
Steps
Result
Naive PDC (no bridging) = 44 covered days / 60 window days = 0.733 — below the 0.80 adherence threshold. Bridged PDC (carry-over) = 58 covered days / 60 window days = 0.967 — well above the threshold. The single decision to bridge the 20-day hospital stay adds 14 covered days (the inpatient days beyond Fill A's supply) and eliminates a phantom gap, moving Maria from 'non-adherent' to 'highly adherent'.
Inpatient Claim
Facility (inpatient) claim for the same patient — the hospital stay visible here, but no drug NDC appears because the drug cost is bundled into the hospital bill.
| person_id | admit_date | discharge_date | stay_days |
|---|---|---|---|
| 2001 | 2024-01-10 | 2024-01-29 | 20 |
Trade-offs
Runnable example
Apply a bridging policy to outpatient exposure days. Required inputs (cleaned, deduped): fills : person_id, fill_date (datetime), days_supply (int) stays : person_id, admit_date (datetime), discharge_date (datetime) # from facility/institutional claims window : person_id, obs_start (datetime), obs_end (datetime) #...
import pandas as pd
import numpy as np
def _covered_dates(fills: pd.DataFrame) -> set:
# Days covered by outpatient supply: each fill covers [fill_date, fill_date + days_supply - 1].
out = set()
for _, r in fills.iterrows():
out.update(pd.date_range(r["fill_date"],
r["fill_date"] + pd.Timedelta(days=int(r["days_supply"]) - 1)))
return out
def _inpatient_dates(stays: pd.DataFrame) -> set:
out = set()
for _, r in stays.iterrows():
out.update(pd.date_range(r["admit_date"], r["discharge_date"]))
return out
def pdc_with_bridging(fills, stays, obs_start, obs_end, policy="carryover") -> float:
window = set(pd.date_range(obs_start, obs_end))
inpatient = _inpatient_dates(stays) & window
covered = _covered_dates(fills) & window
if policy == "carryover":
covered = covered | inpatient # assume the drug continued in hospital
denom = window
elif policy == "censor":
covered = covered - inpatient # inpatient days observable for neither num nor denom
denom = window - inpatient # PQA: remove institutional days from the denominator
elif policy == "gap":
covered = covered - inpatient # inpatient days count as uncovered
denom = window
else:
raise ValueError(f"unknown policy: {policy}")
return len(covered & denom) / len(denom) if denom else np.nanApply a bridging policy to outpatient exposure days with data.table. Inputs mirror the Python version: fills : person_id, fill_date (Date), days_supply (integer) stays : person_id, admit_date (Date), discharge_date (Date) Returns PDC for one person under policy in {'carryover','censor','gap'};
library(data.table)
covered_days <- function(fills) {
# Each fill covers fill_date .. fill_date + days_supply - 1.
unique(do.call(c, Map(function(d, n) seq(d, d + n - 1L, by = "day"),
fills$fill_date, as.integer(fills$days_supply))))
}
inpatient_days <- function(stays) {
unique(do.call(c, Map(function(a, b) seq(a, b, by = "day"),
stays$admit_date, stays$discharge_date)))
}
pdc_with_bridging <- function(fills, stays, obs_start, obs_end, policy = "carryover") {
window <- seq(obs_start, obs_end, by = "day")
inpatient <- intersect(inpatient_days(stays), window)
covered <- intersect(covered_days(fills), window)
if (policy == "carryover") { # assume continuation in hospital
covered <- union(covered, inpatient); denom <- window
} else if (policy == "censor") { # PQA: drop institutional days from denominator
covered <- setdiff(covered, inpatient); denom <- setdiff(window, inpatient)
} else if (policy == "gap") { # inpatient days count as uncovered
covered <- setdiff(covered, inpatient); denom <- window
} else stop("unknown policy")
if (length(denom) == 0L) return(NA_real_)
length(intersect(covered, denom)) / length(denom)
}Build a daily exposure spine and apply a bridging policy in SAS (PROC SQL + data step), then compute PDC. Required input datasets (post data-management): work.fills : person_id, fill_date, days_supply work.stays : person_id, admit_date, discharge_date (from facility/institutional claims) work.window : person_id,...
%let policy = CARRYOVER; /* CARRYOVER | CENSOR | GAP */
/* 1. One row per person-day across the observation window. */
data spine;
set work.window;
do day = obs_start to obs_end;
output;
end;
format day date9.;
keep person_id day;
run;
/* 2. Flag days covered by an outpatient fill: [fill_date, fill_date + days_supply - 1]. */
proc sql;
create table covered as
select distinct s.person_id, s.day
from spine s
inner join work.fills f
on f.person_id = s.person_id
and s.day >= f.fill_date
and s.day <= f.fill_date + f.days_supply - 1;
quit;
/* 3. Flag inpatient days from facility claims: [admit_date, discharge_date]. */
proc sql;
create table inpat as
select distinct sp.person_id, sp.day
from spine sp
inner join work.stays st
on st.person_id = sp.person_id
and sp.day >= st.admit_date
and sp.day <= st.discharge_date;
quit;
/* 4. Apply the bridging policy day by day. */
proc sql;
create table flagged as
select sp.person_id, sp.day,
(c.day is not null) as covered_raw,
(i.day is not null) as inpatient
from spine sp
left join covered c on c.person_id = sp.person_id and c.day = sp.day
left join inpat i on i.person_id = sp.person_id and i.day = sp.day;
quit;
data resolved;
set flagged;
length in_denom covered 3;
%if &policy = CARRYOVER %then %do;
in_denom = 1; covered = (covered_raw or inpatient); /* assume continuation */
%end;
%else %if &policy = CENSOR %then %do;
in_denom = (inpatient = 0); covered = (covered_raw and not inpatient); /* PQA: drop inpatient days */
%end;
%else %if &policy = GAP %then %do;
in_denom = 1; covered = (covered_raw and not inpatient); /* inpatient = uncovered */
%end;
run;
/* 5. PDC = covered denominator-days / denominator-days. */
proc sql;
create table pdc as
select person_id,
sum(covered and in_denom) as covered_days,
sum(in_denom) as denom_days,
calculated covered_days / calculated denom_days as pdc
from resolved
group by person_id;
quit;Citations
- [1]Raebel MA, Schmittdiel J, Karter AJ, Konieczny JL, Steiner JF. Standardizing terminology and definitions of medication adherence and persistence in research employing electronic databases. Medical Care. 2013;51(8 Suppl 3):S11-S21.
- [2]Hess LM, Raebel MA, Conner DA, Malone DC. Measurement of adherence in pharmacy administrative databases: a proposal for standard definitions and preferred measures. Annals of Pharmacotherapy. 2006;40(7-8):1280-1288.
- [3]Steiner JF, Prochazka AV. The assessment of refill compliance using pharmacy records: methods, validity, and applications. Journal of Clinical Epidemiology. 1997;50(1):105-116.