Burden of Disease and Cost-of-Illness (COI) Studies
A descriptive economic assessment that quantifies the epidemiologic, humanistic, and economic burden a disease imposes on patients, payers, and society, with cost-of-illness (COI) the dollar-valued component estimating direct, indirect, and intangible costs as total national burden, per-patient figures (PPPY/PPPM), or incremental burden versus disease-free controls.
In plain language
A burden-of-disease study answers one question: how big is this disease's footprint? It adds up all the costs the disease creates — doctor visits, hospital stays, medicines, and lost work — to produce a single dollar figure for the whole population. A cost-of-illness study is the dollar-valued piece of that accounting; it can report the national total (all patients combined), a per-patient annual average, or the extra cost a sick person bears compared to a healthy similar person. The number is a snapshot of the problem's size, not a verdict on whether any treatment is worth its price.
Burden of disease and cost-of-illness (COI)
studies answer a descriptive question — "how big is the problem?" — not a comparative-effectiveness question. They quantify the epidemiologic burden (incidence, prevalence, mortality, DALYs), the humanistic burden (HRQoL decrements, caregiver impact), and the economic burden (the dollars the disease consumes). COI is the dollar-valued economic component. It is deliberately not a causal contrast of one treatment against another; it is a baseline accounting of what a disease costs, used to justify research investment, support disease-awareness and prevention arguments, frame the denominator for budget-impact and cost-effectiveness work, and populate the "natural history and unmet need" sections of regulatory and HTA dossiers.
Core estimand distinctions (must be pre-specified)
COI has no single number; the "answer" depends on four orthogonal choices that must be fixed in the protocol before any cost is summed: - Prevalence-based vs incidence-based. Prevalence-based COI sums all costs incurred in a calendar window (usually one year) by everyone who has the disease that year, regardless of when it began — the right frame for annual payer budgeting and most claims studies. Incidence-based COI sums the present value of all future costs attributable to the cohort of new cases arising in a period (a lifetime or fixed horizon), requiring survival/cost modelling and discounting — the right frame for prevention value, where averting an incident case avoids a lifetime cost stream. - All-cause vs disease-attributable vs incremental. All-cause costs (every claim for a diseased patient) overstate burden by including unrelated care. Attributable costs restrict to disease-coded claims but undercount downstream sequelae and depend on coding fidelity. Incremental costs — the difference between diseased patients and matched disease-free controls — is the methodologically preferred operationalization of "the burden caused by the disease," because it nets out the background cost of being a comparable person in the same system. - Perspective. Payer/healthcare-system (direct medical only — what claims see) vs societal (adds direct non-medical costs such as transportation and informal care, and indirect costs from lost productivity). The perspective dictates which cost buckets are in scope and must be stated up front; claims alone cannot support a true societal perspective. - Mean vs median. Report the arithmetic mean as the headline per-patient cost. Cost distributions are heavily right-skewed; the mean (not the median) is the policy-relevant quantity because total burden = mean × population, and budgets are denominated in totals. The median systematically understates burden and should never stand alone.
Costing method
Bottom-up sums patient-level resource use × unit costs (or paid/allowed amounts) from micro-data — the claims/EHR workhorse. Top-down allocates aggregate national expenditure by diagnosis proportions — useful for national totals but blind to patient heterogeneity. The two are routinely combined (bottom-up per-patient cost × top-down prevalence).
Pros, cons, and trade-offs
- vs healthcare-costs / PPPM-PPPY: COI is the broader framing (epidemiologic + humanistic + full economic, including indirect and societal costs) used for population priority-setting; per-patient cost metrics are one component of it. Cost: COI is more assumption-heavy (indirect-cost valuation, discounting, prevalence extrapolation) and less granular for a specific therapy's value. Prefer COI when the question is the magnitude of a disease's footprint; prefer plain cost metrics when you only need a standardized per-patient spend. - vs cost-effectiveness analysis (CEA): COI describes burden; it does not compare interventions or produce an ICER, and a large COI figure does not imply an intervention is cost-effective. COI frequently precedes CEA by sizing the addressable cost. Prefer CEA for any "is this intervention worth it?" decision. Treating COI as if it answered the cost-effectiveness question is a category error. - vs budget-impact analysis (BIA): COI is the static current burden; BIA is the forward-looking, population-scaled financial consequence of adopting a new technology over a payer's planning horizon. COI supplies BIA's baseline disease cost. Prefer BIA when a payer needs the affordability/cash-flow answer rather than the size-of-problem answer.
When to use
Sizing the economic footprint of a disease for advocacy, research-prioritization, or value-story framing; generating the "unmet need / natural history" evidence in HTA submissions and FDA/EMA dossiers; establishing the cost baseline that BIA and CEA build on; quantifying disparities in burden (equity-weighted or SDoH-stratified COI).
When NOT to use — and when it is actively misleading
- As a stand-in for treatment value. A high COI number is sometimes wielded to argue a drug is worth its price. It cannot: COI has no comparator and no outcome contrast. Use CEA/BIA for value claims. - All-cause costs presented as "the burden of the disease." All-cause spend in a chronically ill, often elderly, multimorbid population is dominated by other conditions; attributing it wholesale to the index disease inflates burden, sometimes several-fold. Use incremental (matched-control) or carefully validated attributable costing. - Mean cost from a sample with uncontrolled catastrophic outliers. A handful of transplant, ICU, or end-of-life cases can dominate the mean and the national total. Without pre-specified outlier handling and a sensitivity analysis, the headline figure is an artifact of a few records (see cost-outlier-handling). - Cross-perspective or cross-country comparison without harmonization. A payer-perspective US claims COI and a societal European COI are not comparable; mixing them or comparing nominal dollars across years without inflation-adjustment is misleading.
Data-source operational depth
- Administrative claims (FFS or commercial): The workhorse for direct medical bottom-up COI. Costs come from paid or allowed amounts on inpatient, outpatient, professional, and pharmacy claims, ideally split by place of service. Real failure modes: (1) Medicare Advantage / capitated person-time lacks adjudicated FFS claims — utilization is captured as encounters with no reliable dollar amounts, so MA-only enrollees silently produce near-zero costs and bias the mean down; restrict to FFS Parts A/B/D (or commercial members with a genuine pharmacy + medical benefit) and exclude MA-only spans. (2) Right-skew and catastrophic outliers dominate the mean — winsorize (e.g., at the 99th–99.5th percentile) or use gamma/log-link GLM, and report the untrimmed result as a sensitivity. (3) Truncation at enrollment ends and at death creates partial person-time; annualize on observed enrolled days (PPPY = total cost ÷ enrolled person-days × 365), not on a naive 12-month assumption, or burden of high-cost end-of-life care is dropped. (4) Claims see no indirect costs, no out-of-pocket beyond the claim, and limited long-term care — a payer-perspective ceiling that must be stated. - EHR: Strong clinical detail (severity, labs, stage) sharpening case definition and risk adjustment, but charges or RVUs are not true costs and capture is visit-driven; patients who leave the system are differentially lost. Link to claims or apply cost-to-charge ratios before reporting dollars. - Registry + survey: Best for incidence/prevalence and patient-reported humanistic and indirect burden (work loss, caregiver hours via human-capital or friction-cost valuation); typically must be linked to claims for credible direct costs. National surveys (e.g., MEPS) anchor out-of-pocket and indirect components claims cannot see. - Linked claims–EHR–registry–vital-records: The ideal substrate (severity + complete spend + reliable mortality for end-of-life and incidence-based costing), at the price of linkage selection and date-reconciliation work.
Worked claims example (incremental, prevalence-based, payer perspective)
Question: the one-year incremental direct medical cost of adult psoriatic arthritis (PsA) in a commercial + Medicare FFS database. (1) Cases: ≥2 PsA diagnoses (ICD-10 L40.5x/M07.x) ≥30 days apart in 2022; index_date = first PsA claim. (2) Continuous enrollment: require medical + pharmacy enrollment for the full 12-month measurement year (2022) with FFS-observable spend; exclude MA-only person-time so costs are real, not missing. (3) Disease-free controls: sample patients with no PsA and no psoriasis diagnosis ever, exact-matched 1:3 on age band, sex, region, and index year, and (optionally) propensity-matched on baseline comorbidity burden; assign each control the case's index_date so measurement windows align. (4) Cost capture: sum allowed amounts across inpatient, outpatient, professional, and pharmacy claims over the 12-month window; if enrollment is partial, annualize as cost ÷ enrolled_days × 365. (5) Incremental cost = mean(case cost) − mean(matched-control cost), the burden attributable to PsA. (6) Skew + outliers: winsorize total cost at the 99.5th percentile and fit a gamma GLM with a log link (Manning–Mullahy family check) for the adjusted incremental cost; report both raw and modelled means. (7) National total = incremental PPPY × prevalent PsA population (from the same data or an external prevalence estimate). (8) Sensitivity: all-cause vs attributable costing, winsorization threshold, payer vs (where linkable) societal perspective, and discount/inflation adjustment if pooling across years. Reporting should state perspective, time horizon, epidemiological approach, costing method, and both per-patient and national totals, and — increasingly expected by HTA — an equity or SDoH-stratified view of how burden concentrates.
Interpreting the output
A prevalence-based COI study reports a national annual burden of type 2 diabetes of $358.4 billion: $268.8 billion in direct medical costs (75%) and $89.6 billion in indirect costs from lost productivity (25%), based on 28 million prevalent cases and a mean per-patient direct cost of approximately $12,800 per year.
(1) Formal interpretation. The $358.4 billion figure is a prevalence-based, societal-perspective annual accounting total — it sums all costs incurred by everyone with the disease in the study year, not the discounted lifetime cost stream of new cases. It is not a causal estimate of what diabetes caused; it is the aggregate economic footprint of a defined prevalent population. The 75/25 direct/ indirect split depends on the human-capital method for indirect costs and would shift with the friction-cost or opportunity-cost approach. National totals are computed as per-patient cost × prevalent case count, so they inherit uncertainty from both the cost model (typically right-skewed, mean-driven) and the epidemiologic prevalence estimate. Double-counting of comorbidity costs is a known limitation of gross (all-cause) costing.
(2) Practical interpretation. For a health system or policymaker, the $12,800 per-patient figure is the lever for formulary and prevention decisions — reducing it by 10% across 28 million patients saves approximately $35.8 billion nationally. The $358.4B headline justifies research investment and frames HTA value arguments, but reviewers will ask whether an incremental (matched-control) design was used; if not, the total should be labeled a gross accounting estimate, not a causal burden.
Worked example
Scenario
Imagine you are asked to estimate the total annual economic burden of type 2 diabetes in the United States. You have a published prevalence figure (28 million adults with the diagnosis) and a per-patient annual cost estimate from a claims database study that separates direct medical spending from indirect productivity losses. Your job is to multiply those two numbers together for each cost category and then add the categories up to reach a national total.
Dataset
Summary inputs for a prevalence-based cost-of-illness calculation. Each row is one cost category; the right column shows the per-patient annual average from claims and survey data.
| cost_category | cost_type | per_patient_annual_usd |
|---|---|---|
| Hospital and outpatient visits | Direct medical | 5200 |
| Prescription drugs | Direct medical | 4400 |
| Lost workdays and reduced productivity | Indirect | 3200 |
Steps
Add the two direct medical rows to get the total direct medical cost per patient: $5,200 + $4,400 = $9,600 per patient per year.
The indirect cost row stands alone: $3,200 per patient per year.
Total per-patient annual cost = direct + indirect = $9,600 + $3,200 = $12,800 per patient per year.
Multiply direct medical cost per patient by prevalence to get the national direct medical burden: $9,600 x 28,000,000 = $268,800,000,000.
Multiply indirect cost per patient by prevalence to get the national indirect burden: $3,200 x 28,000,000 = $89,600,000,000.
Add the two national totals: $268,800,000,000 + $89,600,000,000 = $358,400,000,000.
Result
Total annual national burden of type 2 diabetes = $358.4 billion. Direct medical costs account for $268.8 billion (75%) and indirect productivity losses account for $89.6 billion (25%). These figures come from multiplying the per-patient annual cost of $12,800 by the 28 million prevalent cases: 28,000,000 x $12,800 = $358,400,000,000.
Runnable example
python implementation
Prevalence-based, incremental (matched-control) direct-medical COI from claims-style inputs. Required inputs (already cleaned, one measurement year): members : person_id, age, sex, region, is_case (bool), enrolled_days (FFS-observable days in the year,...
import pandas as pd
import numpy as np
DAYS_IN_YEAR = 365.0
WINSOR_Q = 0.995 # cap catastrophic outliers; report untrimmed as sensitivity
N_CONTROLS = 3 # 1:3 exact matching
def annualized_cost(members: pd.DataFrame, claims: pd.DataFrame) -> pd.DataFrame:
# Total paid per person over the year, then annualize on observed FFS-enrolled days.
total = (claims.groupby("person_id")["paid_amount"].sum()
.rename("total_paid").reset_index())
df = members.merge(total, on="person_id", how="left")
df["total_paid"] = df["total_paid"].fillna(0.0) # enrolled, no claims -> zero cost (not missing)
df["cost_pppy"] = df["total_paid"] / df["enrolled_days"] * DAYS_IN_YEAR
return df
def exact_match(df: pd.DataFrame, k: int = N_CONTROLS, seed: int = 1) -> pd.DataFrame:
# Exact 1:k matching of disease-free controls to cases on age band, sex, region.
rng = np.random.default_rng(seed)
df = df.copy()
df["age_band"] = pd.cut(df["age"], [0, 17, 44, 64, 200],
labels=["0-17", "18-44", "45-64", "65+"])
keys = ["age_band", "sex", "region"]
out = []
for _, stratum in df.groupby(keys, observed=True):
cases = stratum[stratum["is_case"]]
ctrls = stratum[~stratum["is_case"]]
if cases.empty or ctrls.empty:
continue # no support in this cell -> dropped
take = min(len(ctrls), len(cases) * k)
out.append(cases)
out.append(ctrls.sample(take, random_state=int(rng.integers(1e9))))
return pd.concat(out, ignore_index=True)
def incremental_coi(members, claims):
df = annualized_cost(members, claims)
matched = exact_match(df)
cap = matched["cost_pppy"].quantile(WINSOR_Q)
matched["cost_w"] = matched["cost_pppy"].clip(upper=cap)
mean_case = matched.loc[matched["is_case"], "cost_w"].mean()
mean_ctrl = matched.loc[~matched["is_case"], "cost_w"].mean()
return {
"mean_case_pppy": mean_case,
"mean_control_pppy": mean_ctrl,
"incremental_pppy": mean_case - mean_ctrl, # burden attributable to the disease
"winsor_cap": cap,
"n_cases": int(matched["is_case"].sum()),
}r implementation
Prevalence-based, incremental direct-medical COI in R with a gamma GLM for the skewed cost. Inputs mirror Python: members : person_id, age, sex, region, is_case (logical), enrolled_days claims : person_id, paid_amount, pos The gamma/log-link GLM gives an...
library(data.table)
coi_incremental <- function(members, claims, winsor_q = 0.995) {
setDT(members); setDT(claims)
# Annualize total paid on FFS-enrolled days (enrolled-but-no-claims -> 0, not NA).
tot <- claims[, .(total_paid = sum(paid_amount)), by = person_id]
df <- merge(members, tot, by = "person_id", all.x = TRUE)
df[is.na(total_paid), total_paid := 0]
df[, cost_pppy := total_paid / enrolled_days * 365]
df[, age_band := cut(age, c(0, 17, 44, 64, Inf),
labels = c("0-17", "18-44", "45-64", "65+"))]
# Winsorize catastrophic outliers; keep raw for a sensitivity run.
cap <- quantile(df$cost_pppy, winsor_q, names = FALSE)
df[, cost_w := pmin(cost_pppy, cap)]
# Two-part model for skewed cost with a mass at zero (enrolled-but-no-claims):
# part 1 = logistic for Pr(any cost > 0); part 2 = Gamma/log GLM on POSITIVE cost only
# (Gamma's support is y > 0, so it must be fit on the positives, not on a +1-shifted
# series -- the +1 shift biases the mean and is not the right fix for log(0)).
# E[cost] = Pr(cost > 0) * E[cost | cost > 0], so the adjusted prediction multiplies the parts.
df[, any_cost := as.integer(cost_w > 0)]
fit_p1 <- glm(any_cost ~ is_case + age_band + sex + region,
family = binomial(link = "logit"), data = df)
fit_p2 <- glm(cost_w ~ is_case + age_band + sex + region,
family = Gamma(link = "log"), data = df[cost_w > 0])
# Adjusted incremental cost = predicted(case) - predicted(control) at the reference profile.
base <- df[1]; base$age_band <- "45-64"; base$sex <- df[, names(sort(table(sex), TRUE))[1]]
case_row <- copy(base); case_row$is_case <- TRUE
ctrl_row <- copy(base); ctrl_row$is_case <- FALSE
pred_2p <- function(row) predict(fit_p1, row, type = "response") *
predict(fit_p2, row, type = "response")
pc <- pred_2p(case_row)
pk <- pred_2p(ctrl_row)
list(adjusted_incremental_pppy = unname(pc - pk),
winsor_cap = cap, n_cases = df[is_case == TRUE, .N])
}