International Real-World Data Sources
The major non-US real-world data families and what each is best suited for: UK CPRD (primary care linkable to HES hospital data and ONS death, prescribing-based exposure), OpenSAFELY's trusted research environment, the Nordic national registries (Denmark, Sweden, Norway, Finland — personal-identifier lifetime linkage, dispensing-based exposure, near-complete population coverage — the global benchmark for long-horizon drug safety), Germany's GePaRD, France's SNDS, the Netherlands' PHARMO, Japan's MID-NET, JMDC, and NDB, and the South Korean HIRA and Taiwanese NHIRD national insurance databases; all use ICD-10 WHO coding and ATC drug classification rather than ICD-10-CM and NDC, and their governance models range from trusted research environments to licensed data extracts and federated network access via DARWIN EU and EHDEN.
In plain language
Outside the United States, most high-income countries maintain nationwide health databases that cover every resident — not just those with a particular employer or insurance plan — so patients can be followed for years or decades without losing track of them when they change jobs. The UK's CPRD database records what doctors prescribed; the Nordic countries (Denmark, Sweden, Norway, Finland) go one step further and record what patients actually picked up at the pharmacy, using a national identification number that links every hospital stay, prescription, and death certificate for the same person across their lifetime. These sources use different drug and diagnosis codes than the US (ATC codes for drugs instead of NDC numbers; international ICD-10 codes for diagnoses instead of the US clinical modification), so American algorithms cannot be copied directly — but the near-complete follow-up and absence of insurance-dropout gaps make them the global gold standard for detecting rare, late-appearing drug side effects.
The non-US real-world data landscape
Outside the United States, real-world health data are generated by single-payer national health systems, universal social insurance schemes, and population-wide administrative registers — not by a patchwork of competing private payers. This structural difference has two decisive consequences for research. First, disenrollment does not exist: a resident of Denmark, Sweden, or Taiwan remains in the register until death or emigration, so follow-up is not truncated by job change, plan switching, or insurer exit. Second, drug exposure is captured through national prescription registries that record every dispensed item with near-complete coverage. The result is a set of data resources that excel at long-horizon drug safety, population incidence, and rare-exposure studies while imposing their own constraints — different coding systems, governance barriers, prescribing-versus- dispensing distinctions, and varying out-of-hospital drug capture — that must be understood before designing a study or transporting a finding.
United Kingdom — CPRD and OpenSAFELY
The Clinical Practice Research Datalink (CPRD) is the UK's principal primary-care research database. It captures longitudinal GP records — diagnoses, consultations, referrals, test results, and prescriptions — from practices using the Vision and Emis electronic systems, covering roughly 20% of the UK population with demographics broadly representative of England. A critical distinction: CPRD records the GP's issued prescription (the prescribing event), not the patient's actual pharmacy dispensation. A prescription that was issued but not collected or not filled does not generate a subsequent record, so CPRD exposure measurement differs fundamentally from US fill-date claims or Nordic dispensing records. CPRD can be linked deterministically to Hospital Episode Statistics (HES, covering all NHS inpatient and outpatient care), the ONS mortality registry (Office for National Statistics, providing death dates and causes), the National Cancer Registry, and the Index of Multiple Deprivation — enabling the richer covariate and outcome profiles that primary care alone cannot supply. CPRD's representativeness strength is its longitudinal depth and socioeconomic diversity, but its prescribing-not-dispensing exposure definition and its restriction to GP-registered patients (immigrants, prisoners, and some high-turnover urban populations are under-represented) are the primary threats to validity in comparative-effectiveness and adherence studies.
OpenSAFELY is a different model: rather than a licensed extract, it is a trusted research environment (TRE) in which approved analysts execute code against GP record data that never leaves NHS servers. The result is near-real-time, near-complete primary-care coverage of England (55 million patients) with no data transfer and a full audit trail, at the cost of constrained compute environments and a governance process tied to NHS England approvals.
The Nordic registries — the global benchmark for long-horizon safety
Denmark, Sweden, Norway, and Finland each maintain a system of linked national registers anchored by a unique personal identity number (PIN) that is assigned at birth or immigration and used consistently across all health, social, and administrative records. This single stable identifier enables lifetime individual-level linkage without probabilistic matching or linkage error — the entire population from birth or registration forward. The key registries in each country include:
- Diagnoses: National Patient Registries (hospital inpatient diagnoses, with outpatient
- Drug dispensing: National Prescription Databases that capture every dispensed item
- Death: National Cause-of-Death Registers with near-complete civil registration,
- Additional registries: civil registration (sociodemographics), cancer registries,
The Nordic systems offer near-complete population coverage with no private-care leakage in countries where most health care is publicly funded. The defining advantage for pharmacoepidemiology is the absence of disenrollment censoring: a Danish cohort of 100 new users loses participants only to death or emigration over a 2-year window (98 of 100 retained), while a US commercial cohort loses 40 of the same 100 to job change or plan switch. The resulting long, uninterrupted follow-up makes Nordic data the world's gold standard for detecting rare, late-onset adverse drug reactions and for studying drug effects over years to decades. The primary limitation is restricted access: each country requires separate data applications, typically reviewed by a national ethics board and a statistics authority, with data kept on secure servers inside the country.
Western Europe — GePaRD, SNDS, and PHARMO
Germany's GePaRD (German Pharmacoepidemiological Research Database) pools claims from four statutory sickness funds covering roughly 20 million insured persons. Exposure is dispensing-based (pharmacy claims), diagnoses are coded in ICD-10 GM (German Modification, close to ICD-10 WHO), and out-of-pocket drug purchases are not captured. The German statutory-fund system covers approximately 90% of the population, with private insurers covering higher earners separately.
France's SNDS (Système National des Données de Santé) is one of the most comprehensive claims databases in Europe, covering virtually the entire French population (67 million) including public and private sector employees. It links the national health insurance system (SNIIRAM) with the hospital discharge database (PMSI) and the national mortality data, using a pseudonymized but stable identifier. Drug exposure is recorded by dispensed ATC code. The SNDS is operated by the CNAM and requires authorization from the Health Data Hub.
The Netherlands' PHARMO is a network of linked population-based data sources including outpatient pharmacy records, hospital discharges, general practitioner records, and pathology reports in defined geographical catchment areas. Drug exposure is dispensing- based; diagnoses in GP and hospital records are coded in ICPC-2 (GP) and ICD-10 (hospital). PHARMO offers the advantage of an integrated GP-pharmacy-hospital linkage for longitudinal studies.
Asia — Japan, South Korea, and Taiwan
Japan's MID-NET (Medical Information Database Network) is a hospital-based EHR network of roughly 23 academic and general hospitals, providing rich clinical data at the cost of limited population representativeness and complexity of out-of-hospital care capture. JMDC is a commercial claims database of employer-sponsored health insurance funds (predominantly working-age adults), structured similarly to US commercial claims. The National Database of Health Insurance Claims and Specific Health Checkups of Japan (NDB) is the national claims repository covering the entire insured population (essentially the whole country) with drug dispensing, diagnoses, and procedure codes.
South Korea's Health Insurance Review and Assessment Service (HIRA) database covers the entire Korean population under the single-payer National Health Insurance scheme, with drug dispensing records, diagnoses in KCD (Korean Classification of Diseases, ICD-10 compatible), and a stable national identifier. Taiwan's National Health Insurance Research Database (NHIRD) similarly provides near-universal population coverage under Taiwan's single-payer system, with drug claims, inpatient/outpatient records, and ICD-9-CM coding (more recent releases use ICD-10-CM). Both are among the largest and most complete insurance databases in the world.
The EU federation layer — DARWIN EU, EHDEN, and OMOP-mapped networks
The European Health Data & Evidence Network (EHDEN) and the European Medicines Agency's DARWIN EU (Data Analysis and Real-World Interrogation Network) are building federated infrastructure that maps European data sources to a common OMOP CDM and executes distributed network studies without centralizing patient-level data. This layer connects CPRD, SNDS, GePaRD, Nordic registries, and others under a common protocol and codeset — each data source retains governance control while contributing to network-level summaries. DARWIN EU is the EMA's active pharmacovigilance and product evaluation infrastructure, making it the regulatory gateway for post-authorization safety studies (PASS) in Europe. For researchers building multi-country evidence, this OMOP-CDM-based federated model is the path to reproducing the analytic approach described under federated-distributed-network-analysis.
Cross-cutting contrasts with US claims data
Four structural contrasts shape every design decision when working with non-US sources:
(1) Disenrollment censoring vs single-payer completeness. US commercial databases are interrupted by job change, insurance switching, and end of employment at a rate of roughly 20–40% per year in working-age populations; every analysis must apply a continuous-enrollment criterion and treat disenrollment as informative censoring. In Nordic and East Asian single-payer systems, the follow-up record is complete for all in-country care until death or emigration. This is not merely a precision advantage — disenrollment correlated with health status (e.g., patients who become too ill to work) creates a source of dependent censoring that biases US commercial cohort results in ways Nordic data avoids.
(2) Prescribing vs dispensing vs administration exposure capture. US fill claims capture what was dispensed at the pharmacy. CPRD captures the GP's issued prescription (prescribed but not necessarily collected). Nordic/GePaRD/SNDS dispensing registries capture pharmacy collection (closest to US fill claims). Japanese NDB and EHR systems also capture inpatient administration. Drug names are identified by ATC code internationally, not by NDC number; and where days_supply is absent, exposure duration must be estimated from pack size and quantity using the ATC/DDD framework — a fundamentally different computational step.
(3) Coding systems: ICD-10 WHO vs ICD-10-CM; ATC vs NDC. The US uses ICD-10-CM (over 72,000 codes, with US-specific 7th characters and extensions) for diagnoses and NDC (National Drug Code, tied to specific formulations) for drugs. International databases use ICD-10 WHO (approximately 15,000 codes; no 7th-character US extensions) and ATC (a hierarchical classification by therapeutic class and substance), so validated US phenotyping algorithms cannot be copied verbatim — they require adaptation to the available code set. The ATC/DDD system is a route into the atc-ddd-classification concept.
(4) Governance models and access. US commercial databases are typically licensed through data use agreements with commercial vendors. Nordic countries require ethics board approval and data authority registration; data analysis must occur on approved national servers or via a Statistics Denmark-style extract process. The OpenSAFELY and DARWIN EU models go further: the analyst's code runs inside a TRE; only results leave. These governance constraints are not obstacles to work around — they shape study timelines and feasibility and must be scoped into any research plan.
Pros, cons, and trade-offs
Nordic registries (Denmark, Sweden, Norway, Finland): - Pros: near-complete population coverage; personal identity number enables lifetime individual linkage across health, mortality, and socioeconomic registers without probabilistic matching; no disenrollment censoring (exit only at death or emigration); dispensing-based exposure; gold standard for long-horizon safety studies. - Cons: restricted access requiring ethics board approval and data authority registration (multi-country projects multiply governance complexity); drug exposure requires ATC/DDD conversion rather than US-style days_supply; limited non-prescription and OTC drug capture; GP-level data less readily available than in the UK. - When to prefer: long-horizon drug safety (years to decades); rare adverse events; full life-course linkage; studies where disenrollment bias is a primary threat.
UK CPRD: - Pros: detailed longitudinal primary-care data; socioeconomic and regional diversity; linkable to HES, ONS death, and cancer registry; established research infrastructure with CPRD-specific validation literature. - Cons: prescribing (not dispensing) exposure — a patient who did not collect a GP prescription generates no subsequent data signal; GP-registered patients only; representativeness limitations for urban high-turnover populations. - When to prefer: studies where GP consultation behavior and prescribing decisions are central (rather than actual medication-taking); cardiovascular and chronic disease studies with validated CPRD algorithms.
East Asian national databases (HIRA, NHIRD, NDB): - Pros: very large populations under universal coverage; near-complete inpatient and outpatient capture; drug dispensing records; long follow-up periods. - Cons: coding systems differ (ICD-10 compatible but with national modifications; Taiwan used ICD-9-CM in earlier years); ethnic-population homogeneity limits transportability of findings to genetically diverse populations; out-of-pocket medicine purchases not captured; governance varies by country. - When to prefer: rare disease incidence in large populations; east-Asian-specific pharmacogenomic questions; comparative effectiveness in single-payer contexts.
EU federation (DARWIN EU, EHDEN): - Pros: federated OMOP-mapped infrastructure enabling multi-country comparative studies without centralizing patient-level data; regulatory-grade evidence for EMA PASS; harmonized code sets reduce phenotype-translation burden. - Cons: OMOP mapping quality varies across contributing databases; operational timelines for federated studies are long; heterogeneity across contributing sources must be assessed and reported; not all European databases are yet fully integrated. - When to prefer: multi-country regulatory safety evidence; studies where consistency across European health systems is itself the scientific question.
When to use
Use an international RWD source when: (a) a long-horizon drug safety question requires follow-up beyond what US commercial disenrollment will support; (b) the target population is defined by a non-US country's health system or disease burden; (c) a study needs near-complete population coverage without disenrollment censoring (Nordic registries); (d) the research question requires life-course socioeconomic linkage not available in US claims; (e) a regulatory submission to the EMA or an EU member-state authority requires PASS evidence from European sources; or (f) a multi-country federated network study is the evidentiary standard (DARWIN EU / EHDEN context).
When NOT to use — and when it is actively misleading
- *Do not apply US ICD-10-CM phenotyping algorithms directly to non-US sources without
- Do not treat CPRD prescribing records as equivalent to dispensing claims. A GP
- *Do not assume that findings from Nordic populations transport to other populations
- Do not conflate governance approval with data access. Ethics approval and statistics-
- *Do not pool sources that capture drug exposure at different points in the medication
Interpreting the output
The characteristic artifact from international RWD comparisons is the follow-up completeness ratio — the fraction of the original cohort that remains under observation at a given follow-up landmark. In the worked example, two cohorts of 100 new oral anticoagulant users are compared: US commercial (60 of 100 retained at 2 years; follow-up retention = 60 / 100 = 0.60) and Danish national registries (98 of 100 retained; retention = 98 / 100 = 0.98).
(1) Formal interpretation. The US commercial cohort retains 60% of original participants at 2 years, yielding 60 2 = 120 complete person-years at risk from 100 starters (under the simplification that all 40 exiters leave at exactly 2 years). The Danish cohort retains 98%, yielding 98 2 = 196 person-years. The ratio 196 / 120 = 1.63 means the Danish cohort provides 63% more person-years of observation from the same starting N. This difference is not random noise — it is a structural property of the data-generating mechanism, and a US-based disenrollment-censored study that finds a null result for a long-term outcome should be interpreted in light of the follow-up loss. If disenrollment is related to health status (sicker patients leave the workforce and lose commercial coverage), the censoring is informative — biasing the hazard estimate in a direction that cannot be fixed by simply excluding enrolled-only person-time.
(2) Practical interpretation. For a decision-maker evaluating a long-term drug safety question, a Danish registry study and a US commercial claims study of equal starting N are not equivalent: the Danish study produces more follow-up, less informative censoring, and a more complete mortality record. A null result in the US commercial study that is contradicted by a Danish positive finding should prompt investigation of whether disenrollment bias, rather than biology, explains the discordance. Conversely, an effect seen in Denmark may not directly apply to a US payer population with different comorbidities, comedications, and health-seeking behavior — requiring explicit transportability assessment before the finding drives US formulary or prescribing decisions.
Worked example
Scenario
An epidemiologist wants to study 2-year persistence on a direct oral anticoagulant (DOAC) and the long-term risk of intracranial hemorrhage. She has access to a US commercial claims database (MarketScan-equivalent) and the Danish national prescription and patient registries. The table below compares the two sources on four design-critical dimensions; the steps then work through the follow-up completeness gap that changes statistical power and censoring risk.
Dataset
Comparison of US commercial claims versus Danish national registries across four dimensions for a 2-year DOAC persistence and safety study. Each row is one design dimension; values describe what an analyst would encounter working with that source.
| Dimension | US Commercial Claims (MarketScan) | Danish National Registries |
|---|---|---|
| Enrollment and coverage | Employer-sponsored; ages 18-64 typical; enrollment ends when job or plan changes | Universal; covers all Danish residents; coverage ends only at death or emigration |
| Drug exposure captured as | Dispensing claim at pharmacy with days_supply field | Dispensing record from national prescription database; drug identified by ATC code (e.g., B01AF02 for rivaroxaban); exposure duration estimated from pack size and quantity using ATC/DDD framework |
| Diagnosis coding system | ICD-10-CM (US clinical modification; approximately 72000 codes) | ICD-10 WHO (international version; approximately 15000 codes; no US 7th-character extensions) |
| Typical 2-year follow-up retention | 60 of 100 new users remain enrolled (40 disenroll due to job change or plan switch) | 98 of 100 new users remain in the registry (2 die; no disenrollment censoring exists) |
Steps
US commercial follow-up retention rate: 60 / 100 = 0.60 — only 60% of the original cohort provides 2 full years of potential follow-up.
Danish registry retention rate: 98 / 100 = 0.98 — 98% remain under observation because the only exits are death or emigration.
Person-years available from the US cohort (counting only the 60 retained persons at the 2-year mark): 60 * 2 = 120 person-years.
Person-years available from the Danish cohort: 98 * 2 = 196 person-years.
Ratio of available follow-up (Denmark vs US): 196 / 120 = 1.63 — the Danish cohort provides approximately 63% more person-years from the same starting N of 100, entirely because there is no disenrollment censoring.
In the US cohort, the 40 who disenrolled are not a random subset — patients who become too ill to work (and therefore leave employer-sponsored insurance) are sicker than those who stay enrolled, making disenrollment informative rather than random. No increase in sample size fixes this bias.
Drug exposure in the Danish registry must be computed from ATC code B01AF02 (rivaroxaban) with pack size and DDD (defined daily dose = 20 mg for rivaroxaban NVAF indication); there is no days_supply field, so the exposure window is constructed as quantity * pack_size / DDD, where DDD = 1 tablet/day for this drug.
Result
US retention = 60 / 100 = 0.60; Danish retention = 98 / 100 = 0.98. Person-years at 2 years: US = 60 2 = 120; Denmark = 98 2 = 196. Ratio: 196 / 120 = 1.63. The Danish registry delivers 63% more usable follow-up per starting patient and avoids the disenrollment-censoring bias present in the US cohort. Both sources use dispensing-based exposure, but drug coding differs: US uses NDC numbers with days_supply; Danish uses ATC codes with quantity and pack size requiring DDD-based exposure-window construction.
Runnable example
python implementation
Practical data-handling patterns for two key international RWD tasks: (1) constructing a dispensing-based exposure window from Nordic prescription data using ATC code, dispensed quantity, and DDD when no days_supply field is present; (2) checking ICD-10 WHO...
import pandas as pd
# ── 1. Nordic dispensing exposure window (ATC + quantity + pack_size / DDD) ──────────
# No days_supply field exists in Nordic data. Exposure duration is:
# days_covered = quantity * pack_size / ddd_units
# where ddd_units is the Defined Daily Dose for the ATC code (from WHO DDD table).
# For rivaroxaban NVAF (B01AF02): DDD = 1 tablet = 20 mg; 1 pack of 28 tablets covers 28 days.
def nordic_exposure_windows(rx_nordic: pd.DataFrame, ddd_map: pd.DataFrame) -> pd.DataFrame:
"""Compute dispensing-based exposure windows from Nordic prescription data.
Returns one row per dispensing with dispense_date and days_covered computed from
quantity * pack_size / ddd_units. No days_supply field is used or required.
"""
rx = rx_nordic.merge(ddd_map[["atc_code", "ddd_units"]], on="atc_code", how="left")
missing_ddd = rx["ddd_units"].isna()
if missing_ddd.any():
print(f"WARNING: {missing_ddd.sum()} dispensings have no DDD mapping — "
f"excluded from exposure windows. ATC codes: "
f"{rx.loc[missing_ddd, 'atc_code'].unique().tolist()}")
rx = rx[~missing_ddd].copy()
# days_covered = number of whole tablets dispensed / DDD (1 tablet per day assumed)
rx["units_dispensed"] = rx["quantity"] * rx["pack_size"]
rx["days_covered"] = (rx["units_dispensed"] / rx["ddd_units"]).round(0).astype(int)
rx["window_start"] = rx["dispense_date"]
rx["window_end"] = rx["dispense_date"] + pd.to_timedelta(rx["days_covered"], "D")
return rx[["person_id", "atc_code", "dispense_date", "days_covered",
"window_start", "window_end"]]
# Example: 1 pack of 28 rivaroxaban 20 mg tablets, DDD = 1 tablet/day → 28 days covered.
# The equivalent US quantity would be days_supply = 28 in a pharmacy claim.
# ── 2. ICD-10 WHO phenotype coverage check ────────────────────────────────────────────
# US ICD-10-CM algorithms cannot be applied directly to ICD-10 WHO databases.
# Check which US code prefixes have matching codes in the international database.
def check_icd10_who_coverage(
dx_intl: pd.DataFrame,
us_cm_prefixes: list[str], # e.g. ["I21", "I22"] for acute MI (ICD-10-CM)
icd_col: str = "icd10_who",
) -> pd.DataFrame:
"""For each US ICD-10-CM code prefix, report whether matching ICD-10 WHO codes
are present in the database. Codes starting with the same 3-character prefix
are usually comparable; 4th and 5th character extensions may differ between CM and WHO.
Returns a summary DataFrame: prefix, n_unique_who_codes_found, found_in_db (bool).
"""
intl_codes = dx_intl[icd_col].dropna().unique()
rows = []
for prefix in us_cm_prefixes:
matches = [c for c in intl_codes if str(c).startswith(prefix)]
rows.append({
"us_cm_prefix": prefix,
"n_unique_who_codes_found": len(matches),
"found_in_db": len(matches) > 0,
"sample_who_codes": matches[:3], # first 3 for inspection
})
return pd.DataFrame(rows)
# ── 3. Follow-up retention comparison (matches worked example) ────────────────────────
# US commercial: 60 of 100 new users retained at 2 years.
# Danish registry: 98 of 100 retained.
us_retention = 60 / 100 # = 0.60
dk_retention = 98 / 100 # = 0.98
us_py = 60 * 2 # 120 person-years from retained persons
dk_py = 98 * 2 # 196 person-years from retained persons
ratio = dk_py / us_py # 1.63 — Denmark provides 63% more follow-up per 100 starters
print(f"US retention = {us_retention:.2f} | Danish retention = {dk_retention:.2f}")
print(f"US person-years = {us_py} | Danish person-years = {dk_py} | ratio = {ratio:.2f}")r implementation
R/data.table equivalent of the Python implementation: (1) Nordic dispensing exposure windows from ATC code, quantity, and pack size with DDD-based days_covered computation; (2) ICD-10 WHO phenotype coverage check against a US ICD-10-CM prefix list. Inputs...
library(data.table)
# ── 1. Nordic dispensing exposure windows ──────────────────────────────────────────────
# days_covered = (quantity * pack_size) / ddd_units
# No days_supply field exists; DDD table from WHO ATC/DDD index provides the denominator.
nordic_exposure_windows <- function(rx_nordic, ddd_map) {
setDT(rx_nordic); setDT(ddd_map)
rx <- merge(rx_nordic, ddd_map[, .(atc_code, ddd_units)], by = "atc_code", all.x = TRUE)
missing <- rx[is.na(ddd_units)]
if (nrow(missing) > 0L)
warning(sprintf("%d dispensings with no DDD mapping — excluded. ATC: %s",
nrow(missing), paste(unique(missing$atc_code), collapse = ", ")))
rx <- rx[!is.na(ddd_units)]
rx[, units_dispensed := quantity * pack_size]
rx[, days_covered := as.integer(round(units_dispensed / ddd_units))]
rx[, window_start := dispense_date]
rx[, window_end := dispense_date + days_covered]
rx[, .(person_id, atc_code, dispense_date, days_covered, window_start, window_end)]
}
# ── 2. ICD-10 WHO phenotype coverage check ────────────────────────────────────────────
check_icd10_who_coverage <- function(dx_intl, us_cm_prefixes, icd_col = "icd10_who") {
setDT(dx_intl)
intl_codes <- unique(na.omit(dx_intl[[icd_col]]))
rbindlist(lapply(us_cm_prefixes, function(pfx) {
matches <- intl_codes[startsWith(intl_codes, pfx)]
list(
us_cm_prefix = pfx,
n_unique_who_codes = length(matches),
found_in_db = length(matches) > 0L,
sample_who_codes = paste(head(matches, 3L), collapse = "; ")
)
}))
}
# ── 3. Follow-up retention comparison (matches worked example arithmetic) ──────────────
# US commercial: 60 of 100 retained at 2 years. Danish registry: 98 of 100.
us_retention <- 60 / 100 # 0.60
dk_retention <- 98 / 100 # 0.98
us_py <- 60L * 2L # 120 person-years
dk_py <- 98L * 2L # 196 person-years
ratio <- dk_py / us_py # 1.633... ≈ 1.63
message(sprintf("US retention = %.2f | Danish retention = %.2f", us_retention, dk_retention))
message(sprintf("US PY = %d | Danish PY = %d | ratio = %.2f", us_py, dk_py, ratio))