
Data Science Infrastructure for Global Health
An R package for global-health data work. Bundles country metadata
and lightweight clients for the WHO Global Health Observatory,
WHO
Global Health Estimates and UN
Sustainable Development Goals APIs, plus reusable WHO-style themes
for ggplot2 and flextable so that charts and
tables produced from this data look consistent across reports.
Documentation: https://shanlong-who.github.io/DSIR/
Version 0.11.0 is available on CRAN, published on 12 October 2026.
# from CRAN
install.packages("DSIR")
# or the development version from GitHub
# install.packages("remotes")
remotes::install_github("shanlong-who/DSIR")backend = "auto" tries legacy only for codes missing from
the xMart directory or indicators verified to have no observations at
all. Filtered empty results and request failures do not switch
providers. Fallback warns and records the actual provider and
reason.backend = "xmart" or "legacy" for reproducible
analysis. Automatic selection never combines data releases or translates
provider-specific dimension filters. Legacy discovery has a dated
bundled catalog available when its online requests fail.gho_last_updated() for one GHO indicator with the existing
legacy/xMart backend rules, and sdg_last_updated() for the
whole UN SDG database. Results preserve the original time string and
distinguish successful, unavailable and failed timestamp queries.backend = "legacy" or "xmart" for each
request. In 0.11.0, legacy was the compatibility default; 0.13.0 adds
the automatic selection described below.who_std_pop now has 18 age groups from 0-4 to
85+. Align input age groups before rerunning age
standardization.See the release notes and WHO xMart and GHE guide for examples and migration details.
who_countries — a tibble of all 194 WHO
Member States with ISO3, ISO2, UN M49 codes, official and short names,
WHO region, and a is_pic flag for Pacific Island
Countries.
library(DSIR)
library(dplyr)
who_countries
# Filter Member States in the Western Pacific Region
who_countries |>
filter(who_region == "WPR") |>
select(iso3, name_short, is_pic)Regional ISO3 vectors — convenience character
vectors for each WHO region, derived from
who_countries:
wpro_cty # 28 Western Pacific Member States (since May 2025)
afro_cty # 47 African Region Member States
amro_cty # 35 Region of the Americas Member States
searo_cty # 10 South-East Asia Region Member States
euro_cty # 53 European Region Member States
emro_cty # 21 Eastern Mediterranean Region Member States
pic_cty # 14 Pacific Island Country Member States (subset of WPR)iso3_to_region() — quick lookup from
ISO3 codes to WHO regions. Vectorized; returns NA for codes
not matching a Member State.
iso3_to_region("PHL") # "WPR"
iso3_to_region(c("PHL", "FRA", "ZAF", "XYZ")) # "WPR" "EUR" "AFR" NAiso3_to_m49() /
m49_to_iso3() — convert between ISO3 codes and UN
M49 numeric codes in either direction. Useful for moving between GHO
(ISO3) and SDG (M49) workflows. Case-insensitive on the ISO3 side; both
accept zero-padded or bare M49 input on the M49 side; non-Member areas
return NA.
iso3_to_m49("PHL") # "608"
iso3_to_m49(c("PHL", "FRA", "JPN")) # "608" "250" "392"
iso3_to_m49(c("PRI", "PHL")) # NA "608"
m49_to_iso3(c("608", "250", "392")) # "PHL" "FRA" "JPN"
m49_to_iso3(c("076", "76")) # "BRA" "BRA"
m49_to_iso3("900") # NA (world aggregate)In practice you rarely need to call these directly:
sdg_data() and sdg_coverage() accept ISO3
codes for their area argument and convert via
iso3_to_m49() internally, and sdg_clean()
populates its iso3 column via
m49_to_iso3().
theme_dsi() and
theme_dsi_facet() — publication-ready
ggplot2 themes. Use theme_dsi() for
single-panel charts and theme_dsi_facet() for faceted
plots; the facet variant adds panel borders, light strip backgrounds,
and panel spacing tuned for multi-panel layouts.
library(ggplot2)
library(dplyr)
# Single panel — theme_dsi()
who_countries |>
count(who_region) |>
ggplot(aes(reorder(who_region, n), n)) +
geom_col(fill = "#0093D5") +
coord_flip() +
scale_y_dsi_col() +
theme_dsi() +
labs(title = "WHO Member States by region", x = NULL, y = NULL)
# Faceted — theme_dsi_facet()
who_countries |>
count(who_region, is_pic) |>
ggplot(aes(reorder(who_region, n), n, fill = is_pic)) +
geom_col() +
coord_flip() +
scale_y_dsi_col() +
facet_wrap(~ is_pic, labeller = as_labeller(
c(`TRUE` = "Pacific Island Countries", `FALSE` = "Other Member States")
)) +
scale_fill_manual(values = c(`TRUE` = "#0093D5", `FALSE` = "grey70"),
guide = "none") +
theme_dsi_facet() +
labs(title = "WHO Member States by region and PIC status",
x = NULL, y = NULL)scale_y_dsi_col() and
scale_x_dsi_col() — drop-in replacements for
scale_y_continuous() and scale_x_continuous()
that remove the default lower expansion, so columns in bar charts sit
flush with the axis instead of floating above it. Pick the one that
matches where you mapped the value: scale_y_dsi_col() when
value is the y aesthetic (including horizontal
bars made with coord_flip() — the aesthetic is still
y), and scale_x_dsi_col() when
value is the x aesthetic (e.g.
geom_col(aes(value, category))). Both accept any argument
that scale_*_continuous() accepts.
# Vertical bars
ggplot(mtcars, aes(factor(cyl))) +
geom_bar(fill = "#0093D5") +
scale_y_dsi_col() +
theme_dsi() +
labs(title = "Cars by cylinder count", x = "Cylinders", y = NULL)dsi_flextable_defaults() — one-line
setup for flextable formatting (booktabs style, bold
headers, paddings). flextable (>= 0.9.0) is optional;
install it with install.packages("flextable") before using
this helper.
dsi_flextable_defaults()ggpie() — quick pie charts with
automatic percentage labels.
df <- data.frame(
region = c("AFR", "AMR", "EUR", "WPR", "SEAR", "EMR"),
countries = c(47, 35, 53, 28, 10, 21)
)
ggpie(df, "region", "countries", .offset = 1.2)data_snapshot() /
compare_snapshots() (development) — save complete
GHO observations and query context to a local RDS file, then compare two
extracts offline. Matching uses the full geographical, temporal and
dimension key. Incompatible backends, query scopes or unit/measure
definitions stop the comparison; value changes and metadata-only changes
are reported separately.
# Repeat exactly the same query later, using the same backend.
old_data <- gho_data("WHS4_100", area = "PHL", backend = "xmart")
data_snapshot(old_data, file = "snapshots/gho_old.rds")
new_data <- gho_data("WHS4_100", area = "PHL", backend = "xmart")
data_snapshot(new_data, file = "snapshots/gho_new.rds")
result <- compare_snapshots("snapshots/gho_old.rds", "snapshots/gho_new.rds")
result$summary
result$modifiedExisting files are protected by default. For locally filtered or
imported data, declare the complete scope; raw GHO data are
preferred to the default 15-column cleaned output. A provider timestamp,
retrieval time, UTC snapshot creation time and latest observation year
are different concepts. Differences between extracts do not establish
when or why WHO revised data. See the offline snapshot tutorial for a
reproducible simulation and the full comparison contract. The existing
snapshot() expression cache remains available.
geomean() — geometric mean, with
optional weights. Useful for aggregating ratio-based health indicators
where the composite is multiplicative — e.g. UHC service-coverage
tracers.
geomean(c(0.6, 0.8, 0.95)) # ~0.772
geomean(c(0.6, 0.8, 0.95), w = c(2, 1, 1)) # weighted versionaarr() — average annual rate of
reduction, the standard WHO / UNICEF metric for tracking progress in
declining indicators (maternal / child mortality, premature NCD
mortality, stunting). Fits an OLS line to log(value)
against year (the UNICEF-standard method; an endpoint-only
method is also available). Positive values mean the indicator is
declining; multiply by 100 to compare with published tables.
years <- 2000:2015
values <- 100 * (1 - 0.024) ^ (years - 2000)
aarr(years, values) # 0.024 = 2.4%/yr decline
aarr(years, values, method = "endpoint") # first/last years only
# Slots into a grouped summarise() on cleaned indicator data
gho_data("NCDMORT3070", area = wpro_cty, dim1 = "SEX_BTSX") |>
gho_clean() |>
dplyr::summarise(aarr = aarr(year, value_num), .by = iso3)Check availability before downloading. The public GHO directory contains many indicators but any one of them may not cover the countries or years you need. Three lightweight helpers ask the server what is available without transferring observations:
# Yes / no for a given indicator + filter (TRUE / FALSE / NA on failure)
gho_has_data("WHOSIS_000001", area = "FRA")
# Row count the same filter would return — useful for sizing a download
gho_count("WHOSIS_000001", area = wpro_cty)
# Per-country year coverage and observation counts
gho_coverage("WHOSIS_000001", area = c("FRA", "DEU", "JPN"))Check an indicator’s timestamp (experimental).
gho_last_updated() requests the latest non-missing
observation timestamp across all locations, years and dimensions. It
follows the same backend selection rules as gho_data(): an
explicit backend overrides DSIR.who_backend,
with "auto" as the default when neither is set. Missing
timestamps or failed requests do not trigger fallback; automatic
selection checks observation availability first.
gho_last_updated("WHS4_100")
gho_last_updated("WHS4_100", backend = "xmart")
gho_last_updated("WHS4_100", backend = "xmart", diagnostics = TRUE)
# Optional sequential queries for a small set of indicators.
codes <- c("WHS4_100", "NCDMORT3070")
updates <- lapply(codes, gho_last_updated, backend = "legacy")
do.call(rbind, updates)The updated character column preserves the source
timestamp, including any offset or unspecified time zone.
timestamp_field identifies Date (legacy) or
Sys_CommitDateUtc (xMart); neither is a formal publication
date or the latest observation year. Each result has one row, with
status = "ok", "not_available" (no timestamp
supplied), or "failed" (lookup, request or response
validation failed). checked_at is the UTC query start time.
Whole-catalog queries can take considerable time because each indicator
needs a date request and transient failures are retried.
diagnostics = TRUE appends reason,
stage, http_status,
timestamp_kind, provider_route and
provider_indicator; the default eight columns stay
unchanged. directory_not_listed means a successfully read
directory does not list the code, rather than proving it invalid.
http_error and request_failed identify HTTP
and connection failures; timestamp_field_missing and
timestamp_missing identify a missing field and a response
with no non-missing timestamp. Diagnostics make no extra requests and do
not suppress warnings or switch backends.
xMart’s Sys_CommitDateUtc records a system commit that
can reflect data processing. DSIR has not established that legacy
Date records an official modification or publication date.
Shared timestamps do not prove that several indicators’ values changed
together. checked_at is the UTC check start, not a source
modification or observation retrieval time. Use
data_snapshot() and compare_snapshots() to
detect actual differences between retrieved observations.
Fetch and clean. The typical workflow is search → fetch → clean:
gho_indicators() searches xMart when
backend = "auto". Keyword searches cannot establish that an
individual indicator is absent, so they do not switch catalogs. Select
backend = "legacy" for legacy-only codes. If a legacy GHO
request fails, it searches the bundled legacy catalog and warns with its
collection date. attr(result, "catalog_snapshot") records
the snapshot’s source and UTC collection time. The snapshot may omit new
codes or contain outdated names; it does not confirm that observations
are available. Successful empty searches do not trigger fallback. xMart
never uses the legacy snapshot. Search matches names literally: use
"UHC service coverage", not the abbreviation
"UHC SCI", to find names containing those words.
# Search indicators by keyword
gho_indicators("mortality")
# Discover available dimensions for an indicator
gho_dimensions("NCDMORT3070")
gho_dimensions("NCDMORT3070", dimension = "Dim1")
# Fetch country-level data
gho_data("NCDMORT3070", spatial_type = "country")
# Fetch with area and year filters
gho_data(
indicator = "WHOSIS_000001",
area = wpro_cty,
year_from = 2015
)
# Filter breakdown dimensions server-side — e.g. keep only the
# both-sexes rows instead of downloading every stratum. Use
# gho_dimensions() to discover the values available for an indicator.
gho_data("NCDMORT3070", spatial_type = "country", dim1 = "SEX_BTSX")
# Tidy the raw GHO response
raw <- gho_data("NCDMORT3070", spatial_type = "country", area = wpro_cty)
gho_clean(raw)By default, gho_clean() produces the unified
DSIR cleaned-indicator schema — the same 15-column shape
produced by sdg_clean(), so GHO and SDG output can be
combined directly with bind_indicators() (see below).
Output columns: source, id,
indicator, location, iso3,
location_name, year, value,
value_num, low, high,
series, dim1–dim3. Source columns
missing from the raw response (e.g. Low / High
for indicators without confidence intervals) are filled with typed
NA.
To show what each GHO dimension means, set
keep_dimensions = TRUE. The additional
dim1_type, dim2_type, and
dim3_type columns come directly from each observation.
Their meaning can vary between rows: for financial hardship,
dim1_type can be WEALTHQUINTILE,
FINANCIALHARDSHIPCOMPONENT, or DEMOGRAPHIC,
among others.
raw <- gho_data("FINANCIALHARDSHIP_PROPORTIONOFPOP", area = "PHL",
backend = "legacy")
gho_detailed <- gho_clean(raw, keep_dimensions = TRUE, keep_metadata = TRUE)
gho_detailed |>
dplyr::select(provider, iso3, year, value_num, dim1_type, dim1, dim2_type, dim2)As verified on 2026-10-06, this financial-hardship code is absent from the public xMart directory. The example fixes the legacy provider explicitly. The UN SDG workflow below remains separate.
keep_metadata = TRUE also preserves the retrieval
provider, observation identifier, source code and type,
spatial/time types, parent location, update timestamp, time interval,
and comments. Comments are stored in the footnotes
list-column. No dimension type or unit is inferred from an indicator
name or code prefix. Both options default to FALSE.
Same pattern as GHO: search → fetch → clean.
sdg_last_updated() queries the update timestamp of the
whole database:
sdg_last_updated()It returns the same columns and status values as
gho_last_updated(), with scope = "database"
and missing indicator and backend fields. The
UN endpoint accepts no indicator or series filter, so this date does not
mean that every indicator changed then. Series release codes and
metadata-document update dates are not data update timestamps. Source
time zones are preserved; an unspecified time zone is not assumed to be
UTC.
# Browse goals, targets, indicators, and geographic areas
sdg_goals()
sdg_targets()
sdg_indicators()
sdg_areas()
# Search indicators by keyword — AND semantics, case-insensitive
# substring match on the indicator description (client-side filter)
sdg_indicators("mortality")
sdg_indicators("mortality cancer")
sdg_indicators(c("maternal", "mortality"))
# Fetch indicator data — `area` accepts ISO3 codes (converted internally)
# or UN M49 numeric codes. ISO3 lets DSIR's regional vectors be passed
# directly, the same way they work with the GHO client.
sdg_data("3.2.1", area = "PHL", year_from = 2015, year_to = 2023)
sdg_data("3.4.1", area = wpro_cty)
# M49 also works (e.g. when copy-pasting codes from sdg_areas())
sdg_data("3.2.1", area = "608", year_from = 2015, year_to = 2023)
# Tidy the SDG response
raw <- sdg_data("3.2.1", area = "PHL")
sdg_clean(raw)By default, sdg_clean() produces the same
unified 15-column schema as gho_clean():
source, id, indicator,
location, iso3, location_name,
year, value, value_num,
low, high, series,
dim1–dim3. SDG-side fields populate
id (the indicator code, e.g. "3.4.1"),
indicator (the human-readable series description),
location (UN M49 numeric code), iso3 (via
m49_to_iso3() — NA for region / world
aggregates and non-Member areas), location_name, and
series. The GHO-only dim1–dim3
columns are NA for SDG rows. value is kept as
character to preserve non-numeric entries ("<0.1",
aggregate notes); value_num is the numeric coercion
(NA where coercion fails).
Preserving SDG dimensions. sdg_data()
retains named breakdowns inside raw$dimensions. They do not
map to GHO’s three dimension positions. Use
keep_dimensions = TRUE to append all observed SDG
dimensions as character columns such as dim_age,
dim_sex, and dim_quantile. Missing values
remain NA. The default 15-column output omits these
breakdowns, so select the required strata first when using the compact
format. Use keep_metadata = TRUE to also retain units,
nature, and other attributes as attr_* columns.
raw <- sdg_data("3.8.2", area = "PHL")
unique(raw$dimensions) # Inspect actual dimension names and codes
financial_hardship <- sdg_clean(
raw, keep_dimensions = TRUE, keep_metadata = TRUE
)
# National total: use the exact UN names and codes, not GHO codes.
# Series and dimension filters run locally after all pages are fetched.
national <- sdg_data(
"3.8.2", area = "PHL",
series = "SH_OOP_XPD_EARNNET40",
dimensions = list(
Age = "ALLAGE", Location = "ALLAREA", Sex = "BOTHSEX",
Quantile = "_T", Type_of_household = "_T"
)
) |>
sdg_clean(keep_dimensions = TRUE)Discovering dimension codes and labels. This reads official series metadata without downloading the observation table:
codebook <- sdg_dimensions("3.8.2", include_attributes = TRUE)
codebook |>
dplyr::select(series, kind, dimension, code, label, sdmx)The codebook keeps series separate and distinguishes dimensions from
attributes such as units. Use code, not the alternative
sdmx code, in dimensions filters. A listed
category does not guarantee that it occurs in every country’s
observations.
Keeping source context. With
keep_metadata = TRUE, the SDG cleaner appends attributes
(e.g. attr_units, attr_nature),
data_source, time detail/coverage, base period, value type,
and the geographic information URL. All footnotes and linked indicator,
goal, and target codes are preserved in list-columns. This makes no
additional network requests. For example:
financial_hardship |>
dplyr::select(dplyr::any_of(c(
"iso3", "year", "value_num", "attr_units", "attr_nature", "data_source"
)))
head(financial_hardship$footnotes, 1L) # Every note for the first observationUse saveRDS() (or snapshot()) to preserve
these list-columns when saving results. CSV requires an explicit choice
of how to represent multiple notes or links in one cell.
Complete downloads. sdg_data() checks
declared page numbers, page counts, and total row counts before applying
local filters. Inconsistent counts, an unexpected empty page, or a later
request failure produce a warning and no rows; partial observations are
not returned. Counts not supplied by the API cannot be checked.
sdg_coverage() retains these warnings and accepts the same
series and dimensions filters. Without
filters, its counts include all population strata within each location
and series.
For SDG 3.8.2, the UN catalogue checked on 2026-09-30 publishes the
2025-definition series SH_OOP_XPD_EARNNET40. GHO’s
FINANCIALHARDSHIP_PROPORTIONOFPOP also contains total,
large, and impoverishing expenditure components in Dim1;
these components are not separate series in that UN catalogue. Do not
treat every GHO row as the SDG national total or infer missing UN
component rows. See the WHO
definition and components and the UN
series catalogue.
Because both cleaners produce the same schema, you can stack their
output with bind_indicators() and use the
source column to keep track of where each row came
from:
gho <- gho_data("NCDMORT3070", area = wpro_cty) |> gho_clean()
sdg <- sdg_data("3.4.1", area = wpro_cty) |> sdg_clean()
bind_indicators(gho, sdg)Additional columns, including the named dimensions retained by
keep_dimensions = TRUE, are preserved by
bind_indicators(). Inputs without a given column receive
typed missing values. Binding does not harmonise dimension codes or
indicator definitions across the two sources.
Exploring series. A single SDG indicator often
contains several series — for example different vaccines, sex strata, or
causes of death — each with its own country / year coverage.
sdg_coverage() summarises the year range and observation
count per (location, series) so you can see what is
available before deciding which series to analyse.
# 3.b.1 (vaccine coverage) is published as four separate series
sdg_coverage("3.b.1", area = c("156", "608"))
#> location series year_min year_max n_obs
#> 1 156 SH_ACS_DTP3 2000 2023 24
#> 2 156 SH_ACS_HPV 2018 2023 6
#> 3 156 SH_ACS_MCV2 2000 2023 24
#> 4 156 SH_ACS_PCV3 2017 2023 7
#> 5 608 SH_ACS_DTP3 2000 2023 24
#> 6 608 SH_ACS_HPV 2017 2023 7
#> 7 608 SH_ACS_MCV2 2000 2023 24
#> 8 608 SH_ACS_PCV3 2014 2023 10GHO-style has_data() / count() helpers are
intentionally not provided for SDG because SDG data is generally
complete enough that pre-flight checks add little value.
MIT — © 2026 Shanlong Ding
GHO defaults to backend = "auto", preferring the public
xMart API at https://xmart-api-public.who.int. Before
filtering, automatic indicator queries read its directory and make a
bounded availability request (at most one row) for the entire indicator.
The same selection rules apply to data, counts, availability, coverage,
dimension discovery and update timestamps:
| xMart result | Automatic behavior |
|---|---|
| Exact code absent from a successfully read, non-empty directory | Try legacy, with a warning |
| Verified zero observations for the entire indicator | Try legacy, with a warning |
| Indicator has observations, but requested filters match none | Keep the valid empty xMart result |
| HTTP, transport, parsing, schema or route failure | Report failure; do not switch |
| Only some countries or years are available | Return xMart coverage; do not fill gaps from legacy |
Fallback preserves known WHO ISO3/region codes and year filters.
Named dimensions, positional dim1-dim3 filters
and M49/native geography codes block fallback because equivalent filters
have not been established. Dimension discovery can fall back only for
SpatialDim, SpatialDimType,
TimeDim and TimeDimType. Blocked fallback
warns and returns empty/NA without dropping filters. Use an explicit
backend with its native conventions in these cases.
Each automatic result records the actual backend,
requested_backend = "auto" and any
fallback_reason in
attr(result, "who_provenance"); this also applies to scalar
counts and availability results. Raw observations retain
Provider. No result combines providers. Decisions are
checked afresh on subsequent calls. Pin a backend for repeated analysis,
since provider coverage and published estimates may change. The
15-column default of gho_clean() is unchanged.
gho_indicators('mortality', backend = 'xmart')
gho_dimensions('NCDMORT3070', 'DIM_SEX', backend = 'xmart')
ncd <- gho_data('NCDMORT3070', area = 'PHL', year_from = 2020,
year_to = 2021, dimensions = list(DIM_SEX = 'TOTAL'),
backend = 'xmart')
gho_clean(ncd, keep_dimensions = TRUE, keep_metadata = TRUE)Named dimensions carry their meaning directly (dim_sex,
dim_age, etc.). For wide xMart tables,
Dim1-Dim3 follow the source table dimension
schema, ordered by sex, age, then other names. This may differ from old
positional breakdowns. The legacy sex codes and AGEGROUP_
age namespace remain supported in positional filters. Named filters
retain exact native source codes. Prefer named filters when updating
analyses.
Migration checks on 2026-10-06 matched 18 observations per indicator
across France, Japan and the Philippines in 2020-2021.
NCDMORT3070 values and bounds agreed exactly.
WHOSIS_000001 and MDG_0000000001 values and
bounds differed after matching dimension codes; rounding alone did not
explain all differences. DSIR preserves each provider’s published
estimates. Record the provider and retrieval date when comparing
historical analyses. Raw observations have a Provider
column and a who_provenance attribute.
gho_clean(keep_metadata = TRUE) retains row-level origin as
provider, which survives bind_indicators().
Unknown imported origins remain NA. Missing indicator
labels are resolved with the recorded backend, even when the session
option has changed since retrieval.
Failures warn and return empty results without switching providers.
Reference lookups use a ten-minute memory cache. No keys, startup
requests or disk cache are required. Selection follows: explicit
backend argument, then the DSIR.who_backend
option, then "auto". An argument never changes the session
option. To choose a session default once, use
options(DSIR.who_backend = "xmart"). Other advanced
settings are DSIR.who_base_url (xMart HTTPS origin),
DSIR.who_page_size and DSIR.who_max_rows. Use
snapshot() to save a reproducible pull explicitly.
An absent xMart directory code produces a warning. For legacy HTTP
404 responses, DSIR checks the exact code in its directory before
reporting absence. Successful observation queries with no matching rows
give an informational message: gho_has_data() returns
FALSE, gho_count() returns 0L,
and data/coverage queries return empty tables. Failed requests or
malformed responses warn; availability and count queries return
NA, never FALSE or zero.
If xMart redirects a query to an HTML error page, DSIR retries within its three-attempt limit and warns if the service still does not return JSON. An empty result accompanied by this warning is a failed request, not evidence that no matching indicators or observations exist. Retry later. To use the separate legacy GHO service explicitly for a comparison or temporary workaround:
mortality_indicators <- gho_indicators('mortality', backend = 'legacy')The legacy catalog and estimates can differ from xMart. Backend selection applies to GHO functions; GHE continues to use its xMart source.
Explore exact codes, then select a country, year, sex, age, cause and
measure. GHE is a separate module backed by
DEX_CMS/GHE_FULL. It returns long data with one row per
measure. A download needs at least one filter and is limited to one
million source rows by default.
ghe_dimensions('sex')
ghe_dimensions('age')
ghe_dimensions('measure')
ghe_causes('diabetes')
ghe_causes('stroke')
# All published ages, sexes and causes for one country/year
phl_all_causes <- ghe_data(area = 'PHL', year = 2023, measure = 'deaths')
# Philippine all-age, both-sex deaths, all causes, 2023
phl_deaths <- ghe_data(area = 'PHL', year = 2023, sex = 'TOTAL',
age = 'TOTAL', cause = 0, measure = 'deaths')
# Age-specific death rates by sex
phl_rates <- ghe_data(area = 'PHL', year = 2023,
sex = c('FEMALE', 'MALE'), age = 'Y40T44',
cause = 0, measure = 'death_rate')
ghe_coverage(area = 'PHL', sex = 'TOTAL', age = 'TOTAL', cause = 0)
ghe_clean(phl_rates, keep_dimensions = TRUE)Counts are persons or years; rates are per 100,000; shares are
percentages. Count uncertainty bounds are retained. Bounds for rates and
shares are absent in the provider and remain missing. All-age rates are
crude rates. Do not sum overlapping ages or cause-hierarchy totals.
cause_group is a published group, not an invented parent
code. Discovery lists describe the latest release; verify a selection
with ghe_coverage(). New releases can revise earlier
years.
Beginning with DSIR 0.11.0, who_std_pop uses the WHO
2026 Standard Population. Its 18 groups end at 85+. WHO’s
rounded Table 1 percentages sum to 100.02; DSIR normalizes them to 100
and derives a numeric standard million summing to 1,000,000. No finer
split of 0-4 or 85+ is fabricated.
who_std_pop
count <- seq_len(nrow(who_std_pop))
population <- rep(10000, nrow(who_std_pop))
age_standardize(count, population, who_std_pop$weight)See the WHO technical report, Table 1, page 6 (September 2026). The former 21-row object is replaced; align observed age groups explicitly before computing a standardized rate.