| Title: | Curated Micromort and Microlife Risk Datasets |
|---|---|
| Description: | A data package providing curated, cross-sectional snapshots of micromort (acute risk) and microlife (chronic risk) values from authoritative sources including Wikipedia, CDC MMWR, and academic literature. Designed as a reference dataset for risk comparison and communication, not a time-series analysis tool or epidemiological modelling framework. Includes tools for risk comparison, lifestyle analysis, and a Plumber API for data distribution. All data normalized to unified schemas with full provenance tracking. |
| Authors: | John Gavin [aut, cre] |
| Maintainer: | John Gavin <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.2.0 |
| Built: | 2026-06-08 14:55:13 UTC |
| Source: | https://github.com/JohnGavin/micromort |
Returns a tibble of human-readable descriptions and authoritative help URLs
for all activities in common_risks(). Useful for quiz tooltips, API
responses, and dashboards.
activity_descriptions()activity_descriptions()
A tibble with columns:
activity: Activity name (matches common_risks() exactly)
description: 1-2 sentence explanation of the risk
help_url: Authoritative source URL (Wikipedia or similar)
activity_descriptions() activity_descriptions() |> dplyr::filter(grepl("Skydiving", activity))activity_descriptions() activity_descriptions() |> dplyr::filter(grepl("Skydiving", activity))
A curated dataset of acute mortality risks measured in micromorts. One micromort equals a one-in-a-million chance of death.
A tibble with 62 rows and 15 columns:
Unique record identifier (source_id + sequence)
Human-readable activity name
Standardized activity name for grouping
Risk in micromorts (1 = one-in-a-million death risk)
Equivalent in microlives (micromorts × 0.7)
Activity category (Sport, Travel, Medical, etc.)
Time period for risk (per event, per day, per year)
Standardized period (event, day, week, month, year)
Applicable age group (all, 18-49, 65+, etc.)
Geographic scope (global, US, UK, etc.)
Year of data collection
Source identifier (foreign key to risk_sources)
Direct URL to source
Data quality level (high, medium, low)
Date data was retrieved
Data is compiled from multiple sources including Wikipedia, micromorts.rip, and CDC MMWR reports. Multiple estimates for the same activity may exist from different sources.
Wikipedia: https://en.wikipedia.org/wiki/Micromort
micromorts.rip: https://micromorts.rip/
CDC MMWR: https://www.cdc.gov/mmwr/
Howard RA (1980). "On Making Life and Death Decisions." In Schwing & Albers (eds), Societal Risk Assessment.
Other datasets:
chronic_risks(),
risk_sources
# Load the acute risks dataset acute <- load_acute_risks() head(acute) # Filter by category acute |> dplyr::filter(category == "Sport") # Top 10 riskiest activities acute |> dplyr::slice_max(micromorts, n = 10)# Load the acute risks dataset acute <- load_acute_risks() head(acute) # Filter by category acute |> dplyr::filter(category == "Sport") # Top 10 riskiest activities acute |> dplyr::slice_max(micromorts, n = 10)
Calculate total annual micromort exposure from a list of activities.
annual_risk_budget(activities, age = NULL)annual_risk_budget(activities, age = NULL)
activities |
Named numeric vector of activity frequencies per year.
Names should match activity names in |
age |
Optional age for baseline risk calculation |
A tibble with risk budget breakdown including:
Activity name
Times per year
Micromorts per occurrence
Total annual micromorts
Percentage of total risk budget
daily_hazard_rate(), load_acute_risks()
Other analysis:
compare_interventions(),
daily_hazard_rate(),
lifestyle_tradeoff(),
risk_sensitivity(),
toxicological_risk()
# Calculate annual risk from recreational activities annual_risk_budget(c( "Skydiving (US)" = 10, "Scuba diving, trained" = 20, "Running a marathon" = 2 ), age = 35)# Calculate annual risk from recreational activities annual_risk_budget(c( "Skydiving (US)" = 10, "Scuba diving, trained" = 20, "Running a marathon" = 2 ), age = 35)
A microlife represents a 30-minute change in life expectancy per day. This function converts minutes of life expectancy change to microlives.
as_microlife(minutes, use_units = FALSE)as_microlife(minutes, use_units = FALSE)
minutes |
Numeric. Life expectancy change in minutes.
|
use_units |
Logical. If |
Unit definition: 1 microlife = 30 minutes of life expectancy change per day.
Sign convention:
Negative microlives = life expectancy loss (harmful)
Positive microlives = life expectancy gain (beneficial)
Numeric. Value in microlives (same sign as input), or a units
object when use_units = TRUE.
as_micromort(), lle(), chronic_risks()
Other conversion:
as_micromort(),
as_probability(),
lle(),
value_of_micromort()
# Smoking 20 cigarettes/day: each costs ~30 mins = -600 mins total as_microlife(-20 * 30) # -20 microlives (life lost) # Exercise 20 mins/day: gains ~60 mins life expectancy as_microlife(60) # +2 microlives (life gained) # Being 5kg overweight: costs ~30 mins/day as_microlife(-30) # -1 microlife (life lost) # With units tracking as_microlife(60, use_units = TRUE) # 2 [microlife]# Smoking 20 cigarettes/day: each costs ~30 mins = -600 mins total as_microlife(-20 * 30) # -20 microlives (life lost) # Exercise 20 mins/day: gains ~60 mins life expectancy as_microlife(60) # +2 microlives (life gained) # Being 5kg overweight: costs ~30 mins/day as_microlife(-30) # -1 microlife (life lost) # With units tracking as_microlife(60, use_units = TRUE) # 2 [microlife]
A micromort represents a one-in-a-million chance of death. This function converts a raw probability of death into micromorts.
as_micromort(prob, use_units = FALSE)as_micromort(prob, use_units = FALSE)
prob |
Numeric. Probability of death (0 to 1). |
use_units |
Logical. If |
Numeric value in micromorts, or a units object when
use_units = TRUE.
as_probability(), as_microlife(), value_of_micromort()
Other conversion:
as_microlife(),
as_probability(),
lle(),
value_of_micromort()
as_micromort(1/1000000) # 1 micromort (plain numeric) as_micromort(1/10000) # 100 micromorts (plain numeric) as_micromort(1/1000000, use_units = TRUE) # 1 [micromort]as_micromort(1/1000000) # 1 micromort (plain numeric) as_micromort(1/10000) # 100 micromorts (plain numeric) as_micromort(1/1000000, use_units = TRUE) # 1 [micromort]
Convert Micromorts to Probability
as_probability(micromorts)as_probability(micromorts)
micromorts |
Numeric. Risk in micromorts. |
Numeric probability.
as_micromort(), as_microlife()
Other conversion:
as_microlife(),
as_micromort(),
lle(),
value_of_micromort()
as_probability(1) # 1e-6as_probability(1) # 1e-6
Returns a tibble where each row represents ONE risk component of ONE
activity. Different risk types (physical, medical, radiation) are never
mixed in the same row. This is the foundational dataset from which
common_risks() aggregates composite values.
atomic_risks()atomic_risks()
Activities that have not yet been decomposed use component = "all_causes"
and risk_category = "mixed" as honest placeholders.
A tibble with columns:
Unique identifier: {activity_id}_{component}_{condition}
Groups components into one activity
Human-readable activity name with duration
Risk component: "all_causes", "crash", "dvt", "radiation", etc.
"physical", "medical", "radiation", "environmental", "mixed"
Human-readable label for this component
Risk for this component at this duration for this condition
Activity duration this row applies to (NA for non-duration-dependent)
Activity category: "Travel", "Medical", "Daily Life", etc.
Human-readable period: "per day", "per event", etc.
"event", "day", "hour", "year", "month", "period"
Can this component be mitigated?
How to mitigate (if hedgeable)
Estimated percent reduction from hedging
What this risk depends on: "health_profile", "geography", "country", "age", or NA
Condition value: "healthy", "dvt_risk_factors", "high_income", "low_income", "allergic", "all_ages", age groups (e.g. "under_65", "65_74_male", "85_plus_male"), ISO-2 country codes (e.g. "US", "UK"), or NA
Data confidence: "high", "medium", "low", "estimated"
Citation URL
Scaling behavior, caveats
"single_source", "corroborated", or "cross_validated"
Integer count of independent sources checked
Character range (e.g. "0.05-0.15") or NA for point estimates
common_risks() for the aggregated view.
atomic_risks() atomic_risks() |> dplyr::filter(component != "all_causes") atomic_risks() |> dplyr::filter(hedgeable)atomic_risks() atomic_risks() |> dplyr::filter(component != "all_causes") atomic_risks() |> dplyr::filter(hedgeable)
Mortality rates for major cancers stratified by sex and age group, expressed in micromorts per year and daily microlives.
cancer_risks()cancer_risks()
Data from SEER Cancer Statistics (NCI) and American Cancer Society 2024-2026.
A tibble with columns: cancer_type, sex, age_group, deaths_per_100k, micromorts_per_year, microlives_per_day, family_history_rr, rank_by_sex, source_url.
SEER Cancer Statistics Factsheets. National Cancer Institute. https://seer.cancer.gov/statfacts/
Siegel RL, et al. Cancer statistics, 2024. CA Cancer J Clin. 2024;74:12-49.
vaccination_risks(), conditional_risk(), hedged_portfolio()
Other conditional-risk:
conditional_risk(),
hedged_portfolio(),
vaccination_risks()
cancer_risks() cancer_risks() |> dplyr::filter(sex == "Female") cancer_risks() |> dplyr::filter(age_group == "50-64")cancer_risks() cancer_risks() |> dplyr::filter(sex == "Female") cancer_risks() |> dplyr::filter(age_group == "50-64")
Returns daily micromorts from chronic diseases for one or more countries, using a bundled snapshot of IHME Global Burden of Disease data sourced via Our World in Data.
chronic_disease_risks(country = "GBR", year = NULL)chronic_disease_risks(country = "GBR", year = NULL)
country |
Character vector of ISO-3 country codes (e.g. |
year |
Integer or |
The bundled CSV (inst/extdata/owid_chronic_deaths.csv) covers seven
chronic cause categories across ~20 countries. To refresh the snapshot from
the live OWID catalog, run data-raw/owid_chronic_deaths.R.
daily_micromorts = (deaths_per_100k / 365) * 10
Because: annual deaths per 100,000 → divide by 100,000 for annual
probability → divide by 365 for daily probability → multiply by 1,000,000
for micromorts. The 100,000 and 1,000,000 cancel to a factor of 10:
rate / 100,000 / 365 × 1,000,000 = rate / 365 × 10.
A tibble::tibble() with columns:
Disease cause label (character)
Country name (character)
ISO-3 country code (character)
Data year (integer)
Age-standardised deaths per 100,000 per year (double)
Daily micromort risk (double)
Annual micromort risk (double)
Institute for Health Metrics and Evaluation (IHME). Global Burden of Disease Study 2019. Seattle, WA: IHME, 2020. https://www.healthdata.org/research-analysis/gbd
Our World in Data. Cause of Death. https://ourworldindata.org/causes-of-death
chronic_risks() for microlife-based chronic lifestyle factors.
# Default: UK, latest year chronic_disease_risks() # Specific country chronic_disease_risks("USA") # Multiple countries chronic_disease_risks(c("GBR", "USA", "JPN")) # All countries in bundled dataset chronic_disease_risks("all") # Filter by cause after calling chronic_disease_risks("GBR") |> dplyr::filter(cause == "Cardiovascular diseases")# Default: UK, latest year chronic_disease_risks() # Specific country chronic_disease_risks("USA") # Multiple countries chronic_disease_risks(c("GBR", "USA", "JPN")) # All countries in bundled dataset chronic_disease_risks("all") # Filter by cause after calling chronic_disease_risks("GBR") |> dplyr::filter(cause == "Cardiovascular diseases")
Creates candidate question pairs from chronic_risks() for use in an
interactive microlife comparison quiz. Each pair contains two chronic
lifestyle factors, and the player guesses which has the larger absolute
effect on life expectancy (in microlives per day).
chronic_quiz_pairs( min_ratio = 1.1, max_ratio = 2, prefer_cross_category = TRUE, seed = NULL, difficulty = NULL )chronic_quiz_pairs( min_ratio = 1.1, max_ratio = 2, prefer_cross_category = TRUE, seed = NULL, difficulty = NULL )
min_ratio |
Minimum ratio between absolute microlife values in a pair.
Default 1.1. Ignored when |
max_ratio |
Maximum ratio. Default 2.0. Ignored when |
prefer_cross_category |
If |
seed |
Optional random seed for reproducibility. |
difficulty |
Optional difficulty level. One of |
A tibble with columns:
factor_a, microlives_a, direction_a, category_a,
description_a, help_url_a, annual_days_a
factor_b, microlives_b, direction_b, category_b,
description_b, help_url_b, annual_days_b
ratio (max/min of absolute microlife values)
answer ("a" or "b" – whichever factor has the larger absolute effect)
difficulty (only when difficulty is non-NULL)
pairs <- chronic_quiz_pairs(seed = 42) head(pairs) easy <- chronic_quiz_pairs(difficulty = "easy", seed = 42) head(easy)pairs <- chronic_quiz_pairs(seed = 42) head(pairs) easy <- chronic_quiz_pairs(difficulty = "easy", seed = 42) head(easy)
A curated dataset of chronic lifestyle factors measured in microlives. One microlife equals 30 minutes of life expectancy gained or lost.
A dataset of chronic lifestyle factors and their impact on life expectancy, measured in microlives (30 minutes of life expectancy per day).
chronic_risks()chronic_risks()
A tibble with 22 rows and 12 columns:
Unique record identifier
Human-readable factor name
Standardized factor name for grouping
Daily impact in microlives (+/- 30 min units)
Effect direction: "gain" or "loss"
Factor category (Diet, Exercise, Smoking, etc.)
Detailed description of the factor
Days of life gained/lost per year
Source identifier
Direct URL to source
Data quality level
Date data was retrieved
Positive values indicate life expectancy gains; negative values indicate losses. Based on the framework introduced by David Spiegelhalter (2012).
Positive values indicate life expectancy gains; negative values indicate losses. Effects are cumulative over a lifetime of adult exposure (~57 years).
A tibble with columns: factor, microlives_per_day, category, direction, annual_effect_days, source_url.
Spiegelhalter D (2012). "Using speed of ageing and 'microlives' to communicate the effects of lifetime habits and environment." BMJ 2012;345:e8223. doi:10.1136/bmj.e8223
https://en.wikipedia.org/wiki/Microlife
Spiegelhalter D (2012). "Using speed of ageing and 'microlives' to communicate the effects of lifetime habits and environment." BMJ 2012;345:e8223. doi:10.1136/bmj.e8223
https://en.wikipedia.org/wiki/Microlife
https://pubmed.ncbi.nlm.nih.gov/23247978/
Other datasets:
acute_risks,
risk_sources
# Load the chronic risks dataset chronic <- load_chronic_risks() head(chronic) # Factors that reduce life expectancy chronic |> dplyr::filter(direction == "loss") # Factors that increase life expectancy chronic |> dplyr::filter(direction == "gain") chronic_risks() chronic_risks() |> dplyr::filter(direction == "loss") chronic_risks() |> dplyr::filter(category == "Exercise")# Load the chronic risks dataset chronic <- load_chronic_risks() head(chronic) # Factors that reduce life expectancy chronic |> dplyr::filter(direction == "loss") # Factors that increase life expectancy chronic |> dplyr::filter(direction == "gain") chronic_risks() chronic_risks() |> dplyr::filter(direction == "loss") chronic_risks() |> dplyr::filter(category == "Exercise")
Creates candidate question pairs mixing acute risks from common_risks()
(micromorts per event) with chronic risks from chronic_risks() (microlives
per day), converting both to a common microlife scale so they can be
directly compared. Each pair pits one acute activity against one chronic
lifestyle factor and asks which has a larger total impact over
time_period_days.
combined_quiz_pairs(n = 10, time_period_days = 365, seed = NULL)combined_quiz_pairs(n = 10, time_period_days = 365, seed = NULL)
n |
Integer. Number of pairs to generate. Default |
time_period_days |
Numeric. Time period for chronic risk accumulation.
Default |
seed |
Integer or |
The conversion from micromorts to microlives uses the factor
0.7 (1 micromort ≈ 0.7 microlives at age 40). Chronic impact over the
time period is abs(microlives_per_day) × time_period_days.
A tibble with columns:
activity_a, type_a ("acute"), value_a, unit_a ("micromorts"),
category_a, period_a
factor_b, type_b ("chronic"), value_b, unit_b ("microlives/day"),
category_b, direction_b
common_unit ("microlives"), common_value_a, common_value_b
correct_answer ("a" or "b" — whichever has higher impact in common
unit)
ratio (larger / smaller common value)
explanation describing both values and the conversion
pairs <- combined_quiz_pairs(n = 5, seed = 42) pairs[, c("activity_a", "factor_b", "correct_answer", "ratio")] # One year time period (default) pairs_year <- combined_quiz_pairs(n = 10, time_period_days = 365, seed = 1)pairs <- combined_quiz_pairs(n = 5, seed = 42) pairs[, c("activity_a", "factor_b", "correct_answer", "ratio")] # One year time period (default) pairs_year <- combined_quiz_pairs(n = 10, time_period_days = 365, seed = 1)
A comprehensive dataset of activities and their associated acute mortality risk in micromorts, with calculated microlives and source references.
common_risks(profile = list(), duration_hours = NULL)common_risks(profile = list(), duration_hours = NULL)
profile |
A named list of condition variables for filtering conditional
risks, e.g. |
duration_hours |
Optional numeric. For duration-dependent activities,
selects the nearest pre-computed duration bucket within each activity.
All flying variants (2h, 5h, 8h, 12h) are retained. |
Aggregates from atomic_risks(), summing component-level micromorts
per activity.
Micromort: one-in-a-million chance of death (acute risk). Microlife: 30 minutes of life expectancy lost.
Data sources: Wikipedia, micromorts.rip, CDC MMWR, academic literature.
A tibble with columns:
Activity name
Risk in micromorts (1 = 1-in-a-million death probability)
Equivalent microlives (micromorts x 0.7)
Activity category
Human-readable period description
Normalized period type: "event", "day", "hour", "year", "period"
Typical duration in days (for cross-activity comparison)
Micromorts normalized per day
Data source URL
Number of atomic components summed
Percent of total micromorts that are hedgeable
Howard RA (1980). "On Making Life and Death Decisions." In Schwing & Albers (eds), Societal Risk Assessment: How Safe Is Safe Enough?
https://en.wikipedia.org/wiki/Micromort
atomic_risks() for the component-level data.
common_risks() common_risks() |> dplyr::filter(category == "COVID-19") common_risks() |> dplyr::filter(micromorts > 100)common_risks() common_risks() |> dplyr::filter(category == "COVID-19") common_risks() |> dplyr::filter(micromorts > 100)
Compare the impact of multiple lifestyle changes in microlives. Uses the chronic risks dataset to calculate daily, annual, and lifetime effects of interventions.
compare_interventions(interventions)compare_interventions(interventions)
interventions |
Named list of interventions. Each element should have:
|
A tibble comparing effects of each intervention:
Name of the intervention
Original factor name
Original microlives per day
Change multiplier applied
Net microlives gained/lost per day
Days of life gained/lost per year
Years of life gained/lost over 57 years
lifestyle_tradeoff(), daily_hazard_rate(), annual_risk_budget()
Other analysis:
annual_risk_budget(),
daily_hazard_rate(),
lifestyle_tradeoff(),
risk_sensitivity(),
toxicological_risk()
# Compare quitting smoking vs losing weight compare_interventions(list( "Quit 10 cigarettes/day" = list(factor = "Smoking 10 cigarettes", change = -1), "Lose 5kg" = list(factor = "Being 5 kg overweight", change = -1) ))# Compare quitting smoking vs losing weight compare_interventions(list( "Quit 10 cigarettes/day" = list(factor = "Smoking 10 cigarettes", change = -1), "Lose 5kg" = list(factor = "Being 5 kg overweight", change = -1) ))
Compare mortality risk between "hedged" (optimal lifestyle/interventions) and "unhedged" (baseline/suboptimal) scenarios for major disease categories.
conditional_risk(disease = "all")conditional_risk(disease = "all")
disease |
Character. Disease category: "cardiovascular", "cancer", "respiratory", "infectious", or "all". |
A tibble comparing hedged vs unhedged risks in micromorts and microlives.
cancer_risks(), vaccination_risks(), hedged_portfolio()
Other conditional-risk:
cancer_risks(),
hedged_portfolio(),
vaccination_risks()
conditional_risk("cardiovascular") conditional_risk("cancer") conditional_risk("all")conditional_risk("cardiovascular") conditional_risk("cancer") conditional_risk("all")
Mortality risk comparison between vaccinated and unvaccinated populations during the Omicron BA.4/BA.5 period (Sep-Dec 2022).
covid_vaccine_rr()covid_vaccine_rr()
Data source: CDC MMWR Vol. 72, No. 6 (Feb 2023).
A tibble with vaccination status, death rates, micromorts, microlives, and relative risk compared to bivalent booster recipients.
Link SC, et al. COVID-19 Incidence and Death Rates Among Unvaccinated and Fully Vaccinated Adults with and Without Booster Doses During Periods of Delta and Omicron Variant Emergence. MMWR 2023;72:132-138. https://www.cdc.gov/mmwr/volumes/72/wr/mm7206a3.htm
covid_vaccine_rr() covid_vaccine_rr() |> dplyr::filter(age_group == "All ages")covid_vaccine_rr() covid_vaccine_rr() |> dplyr::filter(age_group == "All ages")
Calculates the daily probability of death based on age using
a simplified Gompertz-Makeham mortality model. Returns a central estimate
plus credible bounds derived from ±10% sensitivity on the Gompertz
parameters a (background mortality) and b (initial mortality).
daily_hazard_rate(age, sex = "male")daily_hazard_rate(age, sex = "male")
age |
Age in years |
sex |
"male" or "female" (default: "male") |
The Gompertz hazard is h(x) = a + b * exp(c * x). Bounds are computed by
varying a and b independently by ±10% (four combinations) and taking
the min/max across those combinations.
A tibble with:
Input age
Input sex
Daily probability of death (central estimate)
Daily baseline risk in micromorts (central estimate)
Lower credible bound (micromorts) from ±10% parameter sensitivity
Upper credible bound (micromorts) from ±10% parameter sensitivity
Estimated microlives consumed per day
Reminder that Gompertz parameters are approximate
Human-readable summary
Gompertz B (1825). "On the Nature of the Function Expressive of the Law of Human Mortality." Philosophical Transactions of the Royal Society.
annual_risk_budget(), compare_interventions()
Other analysis:
annual_risk_budget(),
compare_interventions(),
lifestyle_tradeoff(),
risk_sensitivity(),
toxicological_risk()
# Baseline risk at age 30 with credible bounds daily_hazard_rate(30) # Compare male vs female at age 65 daily_hazard_rate(65, "male") daily_hazard_rate(65, "female")# Baseline risk at age 30 with credible bounds daily_hazard_rate(30) # Compare male vs female at age 65 daily_hazard_rate(65, "male") daily_hazard_rate(65, "female")
Population-level factors affecting baseline life expectancy, expressed as microlives per day relative to a reference population.
demographic_factors()demographic_factors()
Based on actuarial data and epidemiological studies.
A tibble with demographic factors and their microlife effects.
Spiegelhalter D (2012). BMJ 2012;345:e8223.
https://en.wikipedia.org/wiki/Microlife
demographic_factors()demographic_factors()
Generates a representative set of combined quiz pairs and writes them to
inst/extdata/combined_quiz_pairs.csv. The Shinylive combined quiz can
read this CSV directly without requiring R computation in the browser.
export_combined_quiz_csv( n = 50L, time_period_days = 365, seed = 42L, path = NULL )export_combined_quiz_csv( n = 50L, time_period_days = 365, seed = 42L, path = NULL )
n |
Integer. Number of pairs to export. Default |
time_period_days |
Numeric. Time period for chronic risk accumulation.
Default |
seed |
Integer. Random seed for reproducibility. Default |
path |
Character. Output file path. Default writes to
|
Path to the written CSV (invisibly).
## Not run: export_combined_quiz_csv() ## End(Not run)## Not run: export_combined_quiz_csv() ## End(Not run)
Returns a tibble of human-readable descriptions and authoritative help URLs
for all factors in chronic_risks(). Useful for quiz tooltips, API
responses, and dashboards.
factor_descriptions()factor_descriptions()
A tibble with columns:
factor: Factor name (matches chronic_risks() exactly)
description: 1-2 sentence explanation of the factor
help_url: Authoritative source URL
factor_descriptions() factor_descriptions() |> dplyr::filter(grepl("exercise", factor, ignore.case = TRUE))factor_descriptions() factor_descriptions() |> dplyr::filter(grepl("exercise", factor, ignore.case = TRUE))
Inserts an HTML <br> before the first opening parenthesis in an activity
name, making quiz buttons more readable by separating the qualifier.
format_activity_name(name)format_activity_name(name)
name |
Character string. The activity name to format. |
A shiny::HTML() object with <br> inserted before (, or the
original string wrapped in HTML() if no parenthesis is present.
format_activity_name("airline pilot (annual radiation)") format_activity_name("Skydiving")format_activity_name("airline pilot (annual radiation)") format_activity_name("Skydiving")
Creates quiz pairs that compare the same disease risk across different
countries, or compare country-specific disease risk against acute
one-off activities. Uses common_risks() with country profiles.
geography_quiz_pairs( countries = c("UK", "NG"), seed = NULL, include_acute = TRUE, difficulty = NULL )geography_quiz_pairs( countries = c("UK", "NG"), seed = NULL, include_acute = TRUE, difficulty = NULL )
countries |
Character vector of ISO-2 country codes to compare.
Default |
seed |
Optional random seed for reproducibility. |
include_acute |
If |
difficulty |
Optional difficulty level: |
A tibble with the same columns as quiz_pairs(), plus a
pair_type column indicating "cross_country" or "disease_vs_acute".
geography_quiz_pairs(countries = c("UK", "NG"), seed = 42)geography_quiz_pairs(countries = c("UK", "NG"), seed = 42)
Calculate total risk reduction from adopting an optimal "hedged" lifestyle across multiple disease categories.
hedged_portfolio( include_diseases = c("cardiovascular", "cancer", "respiratory", "infectious") )hedged_portfolio( include_diseases = c("cardiovascular", "cancer", "respiratory", "infectious") )
include_diseases |
Character vector. Which disease categories to include. Default is all: cardiovascular, cancer, respiratory, infectious. |
A tibble with total hedged vs unhedged comparison and breakdown.
cancer_risks(), vaccination_risks(), conditional_risk()
Other conditional-risk:
cancer_risks(),
conditional_risk(),
vaccination_risks()
hedged_portfolio() hedged_portfolio(include_diseases = c("cardiovascular", "cancer"))hedged_portfolio() hedged_portfolio(include_diseases = c("cardiovascular", "cancer"))
Returns daily micromorts from infectious diseases for one or more countries, using a bundled snapshot of IHME Global Burden of Disease data sourced via Our World in Data.
infectious_disease_risks(country = "GBR", year = NULL)infectious_disease_risks(country = "GBR", year = NULL)
country |
Character vector of ISO-3 country codes (e.g. |
year |
Integer or |
The bundled CSV (inst/extdata/owid_infectious_deaths.csv) covers seven
infectious cause categories across 26 countries. To refresh the snapshot,
run data-raw/owid_infectious_deaths.R.
daily_micromorts = (deaths_per_100k / 365) * 10
Because: annual deaths per 100,000 → divide by 100,000 for annual
probability → divide by 365 for daily probability → multiply by 1,000,000
for micromorts. The 100,000 and 1,000,000 cancel to a factor of 10:
rate / 100,000 / 365 × 1,000,000 = rate / 365 × 10.
A tibble::tibble() with columns:
Disease cause label (character)
Country name (character)
ISO-3 country code (character)
Data year (integer)
Age-standardised deaths per 100,000 per year (double)
Daily micromort risk (double)
Annual micromort risk (double)
Institute for Health Metrics and Evaluation (IHME). Global Burden of Disease Study 2019. Seattle, WA: IHME, 2020. https://www.healthdata.org/research-analysis/gbd
Our World in Data. Cause of Death. https://ourworldindata.org/causes-of-death
chronic_disease_risks() for chronic disease micromort risks by
country.
# Default: UK, latest year infectious_disease_risks() # Specific country infectious_disease_risks("USA") # Multiple countries infectious_disease_risks(c("GBR", "USA", "IND")) # All countries in bundled dataset infectious_disease_risks("all") # Filter by cause after calling infectious_disease_risks("GBR") |> dplyr::filter(cause == "Tuberculosis")# Default: UK, latest year infectious_disease_risks() # Specific country infectious_disease_risks("USA") # Multiple countries infectious_disease_risks(c("GBR", "USA", "IND")) # All countries in bundled dataset infectious_disease_risks("all") # Filter by cause after calling infectious_disease_risks("GBR") |> dplyr::filter(cause == "Tuberculosis")
Computes how well a user's ranking matches the correct ranking using the Kendall tau distance. Counts concordant pairs (user agrees with correct order) vs discordant pairs (user disagrees).
kendall_tau_score(user_order, correct_order)kendall_tau_score(user_order, correct_order)
user_order |
Integer vector of item indices in the user's order (first element = user's #1 pick, i.e. most risky). |
correct_order |
Integer vector of item indices in the correct order. |
A list with:
score: number of concordant pairs
max_score: total number of pairs = k*(k-1)/2
n_concordant: same as score
n_discordant: pairs where user and correct order disagree
pct: percentage score (0-100)
# Perfect score kendall_tau_score(c(1, 2, 3), c(1, 2, 3)) # Completely reversed kendall_tau_score(c(3, 2, 1), c(1, 2, 3)) # One swap kendall_tau_score(c(2, 1, 3), c(1, 2, 3))# Perfect score kendall_tau_score(c(1, 2, 3), c(1, 2, 3)) # Completely reversed kendall_tau_score(c(3, 2, 1), c(1, 2, 3)) # One swap kendall_tau_score(c(2, 1, 3), c(1, 2, 3))
Convenience function returning regions classified as "laggard" - those with lower life expectancy or stagnant improvement trends since 2005.
laggard_regions(country = NULL, year = NULL, sex = NULL)laggard_regions(country = NULL, year = NULL, sex = NULL)
country |
Character vector. Filter to specific countries using ISO 2-letter
codes (e.g., "FR", "DE", "ES"). Default |
year |
Integer or vector. Filter to specific years. Default |
sex |
Character. Filter by sex: "Male", "Female", or "Total". Default |
A tibble filtered to laggard regions only.
regional_life_expectancy(), vanguard_regions()
Other regional:
regional_life_expectancy(),
regional_mortality_multiplier(),
vanguard_regions()
# Laggard regions in 2019 laggard_regions(year = 2019, sex = "Total")# Laggard regions in 2019 laggard_regions(year = 2019, sex = "Total")
Starts a Plumber API server exposing 27 endpoints for accessing micromort
and microlife risk datasets. Every response uses a standard JSON envelope
with data and meta fields including source provenance.
launch_api(host = "127.0.0.1", port = 8080, docs = TRUE)launch_api(host = "127.0.0.1", port = 8080, docs = TRUE)
host |
Host to bind to (default: "127.0.0.1") |
port |
Port to listen on (default: 8080) |
docs |
Enable Swagger documentation (default: TRUE) |
Invisible NULL. Runs the API server until interrupted.
GET /v1/risks/acute — Enriched acute risks (common_risks)
GET /v1/risks/acute/atomic — Atomic risk components
GET /v1/risks/chronic — Chronic microlife gains/losses
GET /v1/risks/cancer — Cancer risk by type/sex/age
GET /v1/risks/vaccination — Vaccination risk reduction
GET /v1/risks/covid-vaccine — COVID vaccine relative risks
GET /v1/risks/conditional — Conditional risk given disease
GET /v1/risks/demographic — Demographic risk factors
GET /v1/regional/life-expectancy — Regional life expectancy
GET /v1/regional/vanguard — Best-performing regions
GET /v1/regional/laggard — Worst-performing regions
GET /v1/regional/mortality-multiplier — Mortality multiplier
GET /v1/radiation/profiles — Exposure by career milestones
GET /v1/radiation/patient-comparison — Patient vs occupational
GET /v1/analysis/equivalence — Risk equivalence lookup
GET /v1/analysis/tradeoff — Lifestyle tradeoff calculator
POST /v1/analysis/exchange-matrix — Risk exchange matrix
POST /v1/analysis/interventions — Compare interventions
POST /v1/analysis/budget — Annual risk budget
POST /v1/analysis/hedged-portfolio — Hedged risk portfolio
GET /v1/convert/to-micromort — Probability to micromorts
GET /v1/convert/to-probability — Micromorts to probability
GET /v1/convert/to-microlife — Minutes to microlives
GET /v1/convert/value — Monetary value of one micromort
GET /v1/convert/lle — Loss of life expectancy
GET /v1/convert/hazard-rate — Daily hazard rate by age
GET /v1/quiz/pairs — Quiz pairs for comparison game
GET /v1/sources — Risk data sources registry
GET /v1/meta — API metadata and endpoint listing
GET /health — Health check
## Not run: launch_api() # Example requests (from another terminal): # curl http://localhost:8080/v1/risks/acute?category=Sport # curl http://localhost:8080/v1/risks/chronic?direction=gain # curl http://localhost:8080/v1/convert/hazard-rate?age=35 ## End(Not run)## Not run: launch_api() # Example requests (from another terminal): # curl http://localhost:8080/v1/risks/acute?category=Sport # curl http://localhost:8080/v1/risks/chronic?direction=gain # curl http://localhost:8080/v1/convert/hazard-rate?age=35 ## End(Not run)
A standalone Shiny app where users compare pairs of chronic lifestyle factors and guess which has the larger absolute effect on life expectancy (microlives per day). Built with bslib cards for a modern UI.
launch_chronic_quiz(n_pairs = NULL, ...)launch_chronic_quiz(n_pairs = NULL, ...)
n_pairs |
Number of question pairs. If |
... |
Additional arguments passed to |
A Shiny app object (runs interactively).
if (interactive()) { launch_chronic_quiz() }if (interactive()) { launch_chronic_quiz() }
Starts an interactive Shiny dashboard for exploring micromort and microlife data.
launch_dashboard(...)launch_dashboard(...)
... |
Additional arguments passed to shiny::runApp() |
Invisible NULL. Runs the dashboard until closed.
## Not run: launch_dashboard() ## End(Not run)## Not run: launch_dashboard() ## End(Not run)
A standalone Shiny app where users compare pairs of risky activities and guess which carries more micromort risk. Built with bslib cards for a modern UI.
launch_quiz(n_pairs = NULL, ...)launch_quiz(n_pairs = NULL, ...)
n_pairs |
Number of question pairs to offer as options (5 or 10).
If |
... |
Additional arguments passed to |
A Shiny app object (runs interactively).
if (interactive()) { launch_quiz() }if (interactive()) { launch_quiz() }
Calculate how much of one good habit compensates for a bad habit.
lifestyle_tradeoff(bad_habit, good_habit)lifestyle_tradeoff(bad_habit, good_habit)
bad_habit |
Factor name of the bad habit (from |
good_habit |
Factor name of the compensating behavior (from |
A tibble showing the tradeoff ratio
compare_interventions(), chronic_risks()
Other analysis:
annual_risk_budget(),
compare_interventions(),
daily_hazard_rate(),
risk_sensitivity(),
toxicological_risk()
# How much exercise offsets 2 cigarettes? lifestyle_tradeoff("Smoking 2 cigarettes", "20 min moderate exercise")# How much exercise offsets 2 cigarettes? lifestyle_tradeoff("Smoking 2 cigarettes", "20 min moderate exercise")
Estimates the average time lost from a lifespan due to a specific risk.
lle(prob, life_expectancy = 40)lle(prob, life_expectancy = 40)
prob |
Numeric. Probability of death. |
life_expectancy |
Numeric. Remaining life expectancy in years (default 40). |
Numeric. Loss of life expectancy in seconds, minutes, or days (estimated).
as_micromort(), as_microlife(), value_of_micromort()
Other conversion:
as_microlife(),
as_micromort(),
as_probability(),
value_of_micromort()
lle(1/1000000, 40) # Loss from 1 micromortlle(1/1000000, 40) # Loss from 1 micromort
Loads the acute risks parquet dataset from inst/extdata/.
load_acute_risks()load_acute_risks()
A tibble with acute risk data
acute <- load_acute_risks() nrow(acute)acute <- load_acute_risks() nrow(acute)
Loads the chronic risks parquet dataset from inst/extdata/.
load_chronic_risks()load_chronic_risks()
A tibble with chronic risk data
chronic <- load_chronic_risks() nrow(chronic)chronic <- load_chronic_risks() nrow(chronic)
Loads the risk sources parquet dataset from inst/extdata/.
load_sources()load_sources()
A tibble with source metadata
sources <- load_sources() nrow(sources)sources <- load_sources() nrow(sources)
Cross-tabulates patient X-ray exposure against occupational career radiation to reveal surprising equivalences. For example, 100 lifetime chest X-rays (10 micromorts) exceeds a 40-year X-ray technician career (2 micromorts).
patient_radiation_comparison( xray_counts = c(1, 10, 100), career_years = c(10, 20, 40) )patient_radiation_comparison( xray_counts = c(1, 10, 100), career_years = c(10, 20, 40) )
xray_counts |
Integer vector of patient X-ray counts to compare.
Default |
career_years |
Integer vector of occupational career durations.
Default |
A tibble with columns: occupation, xray_count, career_years, patient_micromorts, occupational_micromorts, ratio.
radiation_profiles(), atomic_risks()
patient_radiation_comparison() patient_radiation_comparison(xray_counts = c(50, 200), career_years = c(5, 30))patient_radiation_comparison() patient_radiation_comparison(xray_counts = c(50, 200), career_years = c(5, 30))
Creates a stacked bar chart showing the breakdown of atomic risk components for selected activities. Hedgeable components are visually distinguished.
plot_risk_components(activity_ids, profile = list(), risks = NULL)plot_risk_components(activity_ids, profile = list(), risks = NULL)
activity_ids |
Character vector of activity IDs to plot. |
profile |
A named list of condition variables for filtering. |
risks |
Optional pre-computed |
A ggplot2 object.
risk_components(), atomic_risks()
plot_risk_components(c("flying_2h", "flying_8h", "flying_12h"))plot_risk_components(c("flying_2h", "flying_8h", "flying_12h"))
Visualizes the risk of different activities in micromorts.
For filtering by category, use prepare_risks_plot() first.
plot_risks( risks = common_risks(), facet = TRUE, height = 12, label_size = 9, dark = TRUE, guide_lines = TRUE, jitter_ones = TRUE, cluster_bands = TRUE )plot_risks( risks = common_risks(), facet = TRUE, height = 12, label_size = 9, dark = TRUE, guide_lines = TRUE, jitter_ones = TRUE, cluster_bands = TRUE )
risks |
Tibble. Dataframe of risks from |
facet |
Logical. If TRUE, splits plot into COVID-19 and Other panels. Default is TRUE. |
height |
Numeric. Plot height in inches. Default is 12. |
label_size |
Numeric. Y-axis label font size. Default is 9. |
dark |
Logical. If TRUE (default), use |
guide_lines |
Logical. If TRUE (default), add dashed guide lines from y-axis labels to bar starts. |
jitter_ones |
Logical. If TRUE (default), shift 1-micromort values slightly so bars are visible on log scale. |
cluster_bands |
Logical. If TRUE (default), add subtle background bands grouping risks with similar micromort values. |
A ggplot2 object.
prepare_risks_plot(), plot_risks_interactive(), common_risks()
Other visualization:
plot_risks_interactive(),
prepare_risks_plot(),
theme_micromort_dark()
# Default dark plot plot_risks() # Light theme plot_risks(dark = FALSE) # Filter then plot prepare_risks_plot(categories = "Sport") |> plot_risks() # Exclude COVID-19 and show top 20 prepare_risks_plot(exclude_categories = "COVID-19", top_n = 20) |> plot_risks(facet = FALSE)# Default dark plot plot_risks() # Light theme plot_risks(dark = FALSE) # Filter then plot prepare_risks_plot(categories = "Sport") |> plot_risks() # Exclude COVID-19 and show top 20 prepare_risks_plot(exclude_categories = "COVID-19", top_n = 20) |> plot_risks(facet = FALSE)
Creates an interactive plotly visualization of risks with category filtering.
plot_risks_interactive(risks = common_risks())plot_risks_interactive(risks = common_risks())
risks |
Tibble. Dataframe of risks, defaults to |
A plotly object with interactive filtering.
Other visualization:
plot_risks(),
prepare_risks_plot(),
theme_micromort_dark()
if (requireNamespace("plotly", quietly = TRUE)) { plot_risks_interactive() }if (requireNamespace("plotly", quietly = TRUE)) { plot_risks_interactive() }
Filters and prepares risk data for visualization. Use this to filter
categories before passing to plot_risks().
prepare_risks_plot( risks = common_risks(), categories = NULL, exclude_categories = NULL, min_micromorts = 0.1, top_n = NULL )prepare_risks_plot( risks = common_risks(), categories = NULL, exclude_categories = NULL, min_micromorts = 0.1, top_n = NULL )
risks |
Tibble. Dataframe of risks, defaults to |
categories |
Character vector. Categories to include. Use |
exclude_categories |
Character vector. Categories to exclude. Applied
after |
min_micromorts |
Numeric. Minimum micromorts to include (default 0.1 to avoid invisible bars on log scale). |
top_n |
Integer. If specified, return only the top N risks by micromorts. |
A tibble ready for plotting with plot_risks().
Other visualization:
plot_risks(),
plot_risks_interactive(),
theme_micromort_dark()
# All risks prepare_risks_plot() # Only COVID-19 risks prepare_risks_plot(categories = "COVID-19") # Exclude COVID-19 prepare_risks_plot(exclude_categories = "COVID-19") # Multiple categories prepare_risks_plot(categories = c("Sport", "Travel")) # Top 20 risks prepare_risks_plot(top_n = 20) # Chain with plotting prepare_risks_plot(categories = "Sport") |> plot_risks()# All risks prepare_risks_plot() # Only COVID-19 risks prepare_risks_plot(categories = "COVID-19") # Exclude COVID-19 prepare_risks_plot(exclude_categories = "COVID-19") # Multiple categories prepare_risks_plot(categories = c("Sport", "Travel")) # Top 20 risks prepare_risks_plot(top_n = 20) # Chain with plotting prepare_risks_plot(categories = "Sport") |> plot_risks()
Creates candidate question pairs from common_risks() for use in
an interactive risk comparison quiz. Each pair contains two activities
with similar micromort values, making the comparison challenging and
educational.
quiz_pairs( min_ratio = 1.1, max_ratio = 2, prefer_cross_category = TRUE, seed = NULL, difficulty = NULL, profile = list() )quiz_pairs( min_ratio = 1.1, max_ratio = 2, prefer_cross_category = TRUE, seed = NULL, difficulty = NULL, profile = list() )
min_ratio |
Minimum ratio between micromort values in a pair.
Values above 1.0 exclude identical-risk pairs that are unanswerable.
Default 1.1. Ignored when |
max_ratio |
Maximum ratio between micromort values in a pair.
Lower values produce harder questions. Default 2.0. Ignored when
|
prefer_cross_category |
If |
seed |
Optional random seed for reproducibility. |
difficulty |
Optional difficulty level. One of based on data-driven terciles:
When |
profile |
A named list of condition variables for filtering conditional
risks, passed to |
A tibble with columns:
activity_a, micromorts_a, category_a, hedgeable_pct_a, period_a
activity_b, micromorts_b, category_b, hedgeable_pct_b, period_b
description_a, help_url_a, description_b, help_url_b
ratio (max/min of the two micromort values)
answer ("a" or "b" — whichever activity is riskier)
difficulty (only when difficulty is non-NULL)
pairs <- quiz_pairs(seed = 42) head(pairs) # Easy questions (large ratio differences) easy <- quiz_pairs(difficulty = "easy", seed = 42) head(easy) # Country-specific quiz with Nigerian disease risk ng_pairs <- quiz_pairs(profile = list(country = "NG"), seed = 42) head(ng_pairs)pairs <- quiz_pairs(seed = 42) head(pairs) # Easy questions (large ratio differences) easy <- quiz_pairs(difficulty = "easy", seed = 42) head(easy) # Country-specific quiz with Nigerian disease risk ng_pairs <- quiz_pairs(profile = list(country = "NG"), seed = 42) head(ng_pairs)
Compares annual and cumulative radiation exposure across occupational, passenger, and environmental profiles. Uses the Linear No-Threshold (LNT) model for dose-to-risk conversion.
radiation_profiles(milestones = c(10, 20, 40))radiation_profiles(milestones = c(10, 20, 40))
milestones |
Integer vector of career/exposure years for cumulative
columns. Default |
A tibble with columns: activity_id, activity, category, annual_msv, annual_micromorts, milestone columns (mm_Ny for each N), regulatory_limit_msv, xray_equivalents_per_year.
ICRP Publication 103 (2007). Recommendations of the International Commission on Radiological Protection.
Brenner DJ, Hall EJ (2007). "Computed Tomography — An Increasing Source of Radiation Exposure." NEJM 357:2277-2284.
UNSCEAR 2020. Sources, Effects and Risks of Ionizing Radiation.
atomic_risks(), patient_radiation_comparison()
radiation_profiles() radiation_profiles(milestones = c(5, 25, 50))radiation_profiles() radiation_profiles(milestones = c(5, 25, 50))
Creates questions for the ranking quiz by combining acute (micromort) and chronic (microlife) risks, converting to a common Loss of Life Expectancy (LLE) scale, and grouping into rankable sets.
ranking_quiz_questions( tags = NULL, items_per_question = 3L, n_questions = 5L, seed = NULL, difficulty = NULL, profile = list() )ranking_quiz_questions( tags = NULL, items_per_question = 3L, n_questions = 5L, seed = NULL, difficulty = NULL, profile = list() )
tags |
Character vector of tags to include (e.g. "Radiation",
"Travel"). Use |
items_per_question |
Integer. Number of items per question (2, 3, or 4). Default 3. |
n_questions |
Integer. Number of questions to generate. Default 5. |
seed |
Optional integer seed for reproducibility. |
difficulty |
Optional difficulty level: "easy", "medium", "hard", or "mixed". Easy = large LLE spread within question, hard = small spread. |
profile |
A named list of condition variables for filtering conditional
risks, passed to |
A tibble with columns:
question_id, tag, item_name, item_source ("acute"/"chronic"),
lle_minutes, micromorts, microlives_per_day, category,
description, help_url, correct_rank, difficulty
ranking_quiz_questions(tags = "Travel", n_questions = 3, seed = 42)ranking_quiz_questions(tags = "Travel", n_questions = 3, seed = 42)
Returns the mapping between user-facing quiz tags and dataset categories. Tags group related risks across both acute (micromort) and chronic (microlife) datasets for the ranking quiz.
ranking_tag_mapping()ranking_tag_mapping()
A tibble with columns tag, source ("acute"/"chronic"),
category, and optionally pattern (regex for activity-level filtering).
ranking_tag_mapping()ranking_tag_mapping()
Life expectancy at birth by NUTS2 region for Western European countries, based on Eurostat data and the methodology from Bonnet et al. (2026).
regional_life_expectancy( country = NULL, year = NULL, sex = NULL, classification = NULL )regional_life_expectancy( country = NULL, year = NULL, sex = NULL, classification = NULL )
country |
Character vector. Filter to specific countries using ISO 2-letter
codes (e.g., "FR", "DE", "ES"). Default |
year |
Integer or vector. Filter to specific years. Default |
sex |
Character. Filter by sex: "Male", "Female", or "Total". Default |
classification |
Character. Filter by region classification: "vanguard",
"average", or "laggard". Default |
Each row represents one region-year-sex combination, NOT individual survey responses. For example, a dataset with 450 regions × 28 years × 3 sex categories = 37,800 rows of aggregated statistics.
| region_code | year | sex | life_expectancy | Meaning |
| FR10 | 2019 | Male | 82.5 | Avg LE for all males in Île-de-France in 2019 |
| FR10 | 2019 | Female | 87.1 | Avg LE for all females in Île-de-France in 2019 |
| FR10 | 2019 | Total | 84.8 | Avg LE for entire population of Île-de-France in 2019 |
The underlying Eurostat data represents ~400 million people across Western Europe. Life expectancy is calculated from official death registrations and census population counts—not a sample survey.
Primary data from Eurostat dataset demo_r_mlifexp. Regional classifications
based on Bonnet et al. (2026) methodology identifying:
Vanguard regions: Top 20% life expectancy with sustained gains (≥1.5 months/year)
Laggard regions: Bottom 20% life expectancy or stagnant gains (<0.5 months/year)
Average regions: All others
The microlives_vs_eu_avg column converts life expectancy differences to
daily microlives using the approximation: 1 year LE difference ≈ 1.2 microlives/day
(assuming 40 years remaining life expectancy).
Example: A region with +2 years above EU average = +2.4 microlives/day, equivalent to the benefit of 20 minutes daily exercise.
IMPORTANT: Regional life expectancy reflects population averages, NOT individual-level causation. High life expectancy in "vanguard" regions results from multiple factors including:
Healthcare system quality and access
Socioeconomic composition (income, education)
Selection effects (healthy/wealthy people moving to certain regions
Historical and cultural factors
Moving to a high-LE region does NOT guarantee increased personal longevity.
A tibble with columns:
NUTS2 region code (e.g., "FR10" for Île-de-France)
Human-readable region name
ISO 2-letter country code
Data year (1992-2023)
Sex category: "Male", "Female", or "Total"
Life expectancy at birth in years
Daily microlives difference vs EU average
"vanguard", "average", or "laggard" based on 2019 trends
DOI link to source publication
Bonnet F, et al. (2026). "Potential and challenges for sustainable progress in human longevity." Nature Communications 17, 996. doi:10.1038/s41467-026-68828-z
Eurostat (2024). Life expectancy by age, sex and NUTS 2 region (demo_r_mlifexp). https://ec.europa.eu/eurostat/databrowser/product/view/demo_r_mlifexp
demographic_factors(), chronic_risks()
Other regional:
laggard_regions(),
regional_mortality_multiplier(),
vanguard_regions()
# All data regional_life_expectancy() # French regions in 2019 regional_life_expectancy(country = "FR", year = 2019) # Compare vanguard vs laggard regions regional_life_expectancy(year = 2019, sex = "Total") |> dplyr::group_by(classification) |> dplyr::summarise(mean_le = mean(life_expectancy)) # Top 10 regions by life expectancy (2019, Total) regional_life_expectancy(year = 2019, sex = "Total") |> dplyr::slice_max(life_expectancy, n = 10) # Microlives advantage of Catalonia vs EU average regional_life_expectancy(country = "ES", year = 2019, sex = "Total") |> dplyr::filter(grepl("Catalonia", region_name))# All data regional_life_expectancy() # French regions in 2019 regional_life_expectancy(country = "FR", year = 2019) # Compare vanguard vs laggard regions regional_life_expectancy(year = 2019, sex = "Total") |> dplyr::group_by(classification) |> dplyr::summarise(mean_le = mean(life_expectancy)) # Top 10 regions by life expectancy (2019, Total) regional_life_expectancy(year = 2019, sex = "Total") |> dplyr::slice_max(life_expectancy, n = 10) # Microlives advantage of Catalonia vs EU average regional_life_expectancy(country = "ES", year = 2019, sex = "Total") |> dplyr::filter(grepl("Catalonia", region_name))
Calculate a mortality risk multiplier for a region relative to the national or EU average. Useful for adjusting baseline micromort estimates by location.
regional_mortality_multiplier(region_code, reference = "eu", year = 2019)regional_mortality_multiplier(region_code, reference = "eu", year = 2019)
region_code |
Character. NUTS2 region code (e.g., "FR10"). |
reference |
Character. Compare against "national" average or "eu" average. Default is "eu". |
year |
Integer. Reference year. Default is 2019 (pre-COVID). |
The mortality multiplier is derived from life expectancy differences using the approximation that each year of life expectancy difference corresponds to approximately 2.5% difference in annual mortality risk.
A multiplier of 1.0 means average risk; 0.9 means 10% lower risk; 1.1 means 10% higher risk.
A tibble with the region's mortality multiplier and interpretation.
regional_life_expectancy(), demographic_factors()
Other regional:
laggard_regions(),
regional_life_expectancy(),
vanguard_regions()
# Catalonia vs EU average regional_mortality_multiplier("ES51") # Compare to national average regional_mortality_multiplier("ES51", reference = "national")# Catalonia vs EU average regional_mortality_multiplier("ES51") # Compare to national average regional_mortality_multiplier("ES51", reference = "national")
Returns the atomic risk components for a specified activity, optionally filtered by health profile. Useful for understanding what contributes to a composite risk value.
risk_components(activity_id, profile = list(), risks = NULL)risk_components(activity_id, profile = list(), risks = NULL)
activity_id |
Character. The activity ID (e.g., |
profile |
A named list of condition variables, e.g.
|
risks |
Optional pre-computed |
A tibble of atomic components for the requested activity.
atomic_risks(), common_risks()
risk_components("flying_8h") risk_components("flying_8h", profile = list(health_profile = "dvt_risk_factors"))risk_components("flying_8h") risk_components("flying_8h", profile = list(health_profile = "dvt_risk_factors"))
Returns a tibble of authoritative data sources for mortality risk research.
risk_data_sources()risk_data_sources()
A tibble with source names, URLs, types, and descriptions.
risk_data_sources()risk_data_sources()
Compares a reference activity to all other activities by computing the ratio of micromorts. "How many X-rays equal one skydive?"
risk_equivalence(reference, risks = NULL, min_ratio = 0.01, max_ratio = Inf)risk_equivalence(reference, risks = NULL, min_ratio = 0.01, max_ratio = Inf)
reference |
Character. Activity name to use as the reference
(denominator). Must match an |
risks |
A tibble with at least |
min_ratio |
Numeric. Minimum ratio to include (default 0.01). |
max_ratio |
Numeric. Maximum ratio to include (default |
A tibble with columns: activity, micromorts, reference,
reference_micromorts, ratio, equivalence.
risk_equivalence("Chest X-ray (radiation per scan)") risk_equivalence("Skydiving (US)")risk_equivalence("Chest X-ray (radiation per scan)") risk_equivalence("Skydiving (US)")
Creates a cross-comparison matrix showing how many of activity B equal one of activity A, for a selected set of activities.
risk_exchange_matrix(activities = NULL, risks = NULL)risk_exchange_matrix(activities = NULL, risks = NULL)
activities |
Character vector of activity names to include. Defaults to a curated set of 10 diverse activities. |
risks |
A tibble with at least |
A tibble where rows are activities and columns are exchange rates. Cell (i, j) = "how many of activity j equal one of activity i".
risk_exchange_matrix()risk_exchange_matrix()
For duration-dependent activities, finds the nearest pre-computed duration bucket across all variants of an activity family and returns the aggregated risk.
risk_for_duration( activity_prefix, duration_hours, profile = list(), risks = NULL )risk_for_duration( activity_prefix, duration_hours, profile = list(), risks = NULL )
activity_prefix |
Character. Activity family prefix (e.g.,
|
duration_hours |
Numeric. Desired duration in hours. |
profile |
A named list of condition variables. |
risks |
Optional pre-computed |
A tibble with one row per component at the nearest duration bucket, plus summary columns.
risk_components(), common_risks()
risk_for_duration("flying", duration_hours = 7) risk_for_duration("flying", duration_hours = 3)risk_for_duration("flying", duration_hours = 7) risk_for_duration("flying", duration_hours = 3)
Computes how activity micromort rankings shift when the base estimate is
varied by ±pct%. Useful for communicating uncertainty around point
estimates derived from sparse epidemiological data.
risk_sensitivity(activity = NULL, pct = 20)risk_sensitivity(activity = NULL, pct = 20)
activity |
Character scalar — activity name matching a row in
|
pct |
Numeric scalar — percentage variation applied symmetrically
around the base estimate. Default |
Activities are sourced from common_risks(). The rank_change column
reports the absolute number of ranking positions an activity moves between
its low and high estimate when all activities are re-ranked.
A tibble with columns:
Activity name
Base micromort estimate from common_risks()
Low estimate: base * (1 - pct/100)
High estimate: base * (1 + pct/100)
Rank of the activity at the base estimate (1 = highest risk)
Absolute rank positions shifted between low and high estimates
common_risks(), daily_hazard_rate()
Other analysis:
annual_risk_budget(),
compare_interventions(),
daily_hazard_rate(),
lifestyle_tradeoff(),
toxicological_risk()
# Sensitivity for a single activity risk_sensitivity("Skydiving (US)") # Sensitivity for all activities at ±10% risk_sensitivity(pct = 10) # Activities with the largest rank uncertainty risk_sensitivity() |> dplyr::arrange(dplyr::desc(rank_change))# Sensitivity for a single activity risk_sensitivity("Skydiving (US)") # Sensitivity for all activities at ±10% risk_sensitivity(pct = 10) # Activities with the largest rank uncertainty risk_sensitivity() |> dplyr::arrange(dplyr::desc(rank_change))
A registry of data sources used to compile the risk datasets. Each source has a unique identifier that links to records in acute_risks and chronic_risks.
A tibble with 14 rows and 7 columns:
Unique source identifier (e.g., "spiegelhalter_2012")
Full citation or source name
Primary URL
Source type: academic, government, database, book, encyclopedia
Brief description
Types of data: acute, chronic, or both
Date data was retrieved
Other datasets:
acute_risks,
chronic_risks()
# Load the source registry sources <- load_sources() sources # Academic sources sources |> dplyr::filter(type == "Academic")# Load the source registry sources <- load_sources() sources # Academic sources sources |> dplyr::filter(type == "Academic")
A dark-background ggplot2 theme designed for risk comparison plots.
White text on #1a1a1a background with subtle grid lines.
theme_micromort_dark(label_size = 9)theme_micromort_dark(label_size = 9)
label_size |
Numeric. Y-axis label font size. Default is 9. |
A ggplot2 theme object.
Other visualization:
plot_risks(),
plot_risks_interactive(),
prepare_risks_plot()
library(ggplot2) ggplot(mtcars, aes(mpg, wt)) + geom_point(color = "white") + theme_micromort_dark()library(ggplot2) ggplot(mtcars, aes(mpg, wt)) + geom_point(color = "white") + theme_micromort_dark()
Uses human LD50 estimates from inst/extdata/ld50_human.csv to translate a
dose into a micromort risk estimate via linear extrapolation from the
LD50 reference point. At the LD50, 50% lethality equals 500,000 micromorts.
toxicological_risk(substance = NULL, dose_mg = NULL, body_weight_kg = 70)toxicological_risk(substance = NULL, dose_mg = NULL, body_weight_kg = 70)
substance |
Character scalar. Name of substance (case-insensitive,
partial match supported). Pass |
dose_mg |
Numeric scalar. Dose in milligrams. Required when |
body_weight_kg |
Numeric scalar. Body weight in kg. Default |
A tibble. When substance = NULL, returns all substances with
columns substance, route, ld50_mg_per_kg, source. When a
substance is specified, returns a single-row tibble with additional
columns: dose_mg, fraction_of_ld50, micromorts, risk_category.
common_risks(), risk_sensitivity()
Other analysis:
annual_risk_budget(),
compare_interventions(),
daily_hazard_rate(),
lifestyle_tradeoff(),
risk_sensitivity()
# Full reference table toxicological_risk() # Risk from 1 mg nicotine for a 70 kg person toxicological_risk("Nicotine", dose_mg = 1) # Partial name matching toxicological_risk("nico", dose_mg = 1) # Different body weight toxicological_risk("Caffeine", dose_mg = 200, body_weight_kg = 80)# Full reference table toxicological_risk() # Risk from 1 mg nicotine for a 70 kg person toxicological_risk("Nicotine", dose_mg = 1) # Partial name matching toxicological_risk("nico", dose_mg = 1) # Different body weight toxicological_risk("Caffeine", dose_mg = 200, body_weight_kg = 80)
Mortality risk reduction from vaccination schedules compared to unvaccinated baseline, expressed in micromorts avoided per year.
vaccination_risks()vaccination_risks()
Data from CDC, WHO, and Lancet 2024 Global Vaccine Impact Study.
A tibble with vaccination schedules and their risk reduction metrics.
CDC. Health and Economic Benefits of Routine Childhood Immunizations. MMWR 2024;73:1-8. https://www.cdc.gov/mmwr/
Lancet 2024. Contribution of vaccination to improved survival: 50 years of EPI. doi:10.1016/S0140-6736(24)00850-X
cancer_risks(), conditional_risk(), hedged_portfolio()
Other conditional-risk:
cancer_risks(),
conditional_risk(),
hedged_portfolio()
vaccination_risks() vaccination_risks() |> dplyr::filter(country == "US") vaccination_risks() |> dplyr::filter(age_group == "0-5") # Childhood vaccinesvaccination_risks() vaccination_risks() |> dplyr::filter(country == "US") vaccination_risks() |> dplyr::filter(age_group == "0-5") # Childhood vaccines
Calculates the monetary value of one micromort based on the Value of a Statistical Life (VSL).
value_of_micromort(vsl = 1e+07)value_of_micromort(vsl = 1e+07)
vsl |
Numeric. Value of a Statistical Life (default $10,000,000). |
Numeric value of one micromort.
Other conversion:
as_microlife(),
as_micromort(),
as_probability(),
lle()
value_of_micromort(10000000) # $10value_of_micromort(10000000) # $10
Convenience function returning regions classified as "vanguard" - those with the highest life expectancy and sustained improvement trends.
vanguard_regions(country = NULL, year = NULL, sex = NULL)vanguard_regions(country = NULL, year = NULL, sex = NULL)
country |
Character vector. Filter to specific countries using ISO 2-letter
codes (e.g., "FR", "DE", "ES"). Default |
year |
Integer or vector. Filter to specific years. Default |
sex |
Character. Filter by sex: "Male", "Female", or "Total". Default |
A tibble filtered to vanguard regions only.
regional_life_expectancy(), laggard_regions()
Other regional:
laggard_regions(),
regional_life_expectancy(),
regional_mortality_multiplier()
# Vanguard regions in 2019 vanguard_regions(year = 2019, sex = "Total")# Vanguard regions in 2019 vanguard_regions(year = 2019, sex = "Total")