Structuring Markov Models for Multidimensional Health Outcomes

Construction of a Decision-Analytic Markov Model Using Global Burden of Disease Data

CEA
Author

John Graves

Published

December 15, 2023

Support for this work is graciously acknowledged from the Data to Policy initiative administered by Vital Strategies and funded by Bloomberg Philanthropies and the CDC Foundation.

Setup R session
library(tidyverse)
library(here)
library(glue)
library(demography)
library(MortalityLaws)
library(janitor)
library(data.table)
library(expm)
transpose <- purrr::transpose
library(dtplyr)
library(ggsci)
library(directlabels)
library(knitr)
library(kableExtra)
library(hrbrthemes)
library(furrr)
library(tictoc)
library(patchwork)


rate_to_prob <- function(x) 1-exp(-x)
prob_to_rate <- function(x) -log(1-x)

options(scipen = 5) 
select <- dplyr::select
options(knitr.kable.NA = '')

gen_wcc <- function (n_cycles, method = c("Simpson1/3", "half-cycle", "none")) 
{
    if (n_cycles <= 0) {
        stop("Number of cycles should be positive")
    }
    method <- match.arg(method)
    n_cycles <- as.integer(n_cycles)
    if (method == "Simpson1/3") {
        v_cycles <- seq(1, n_cycles + 1)
        v_wcc <- ((v_cycles%%2) == 0) * (2/3) + ((v_cycles%%2) != 
                                                     0) * (4/3)
        v_wcc[1] <- v_wcc[n_cycles + 1] <- 1/3
    }
    if (method == "half-cycle") {
        v_wcc <- rep(1, n_cycles + 1)
        v_wcc[1] <- v_wcc[n_cycles + 1] <- 0.5
    }
    if (method == "none") {
        v_wcc <- rep(1, n_cycles + 1)
    }
    return(v_wcc)
}

age_group_lut <- c(
    "5" = 1,
    "6" = 5,
    "7" = 10,
    "8" = 15,
    "9" = 20,
    "10" = 25,
    "11" = 30,
    "12" = 35,
    "13" = 40,
    "14" = 45,
    "15" = 50,
    "16" = 55,
    "17" = 60,
    "18" = 65,
    "19" = 70,
    "20" = 75,
    "30" = 80,
    "31" = 85,
    "32" = 90,
    "33" = 95,
    "44" = 100,
    "45" = 105,
    "148" = 110,
    "28" = 0
)

lut_age_incidence = 
tibble::tribble(
  ~age_name, ~age,
  "<1 year",  0L,
  "1-4 years",  1L,
  "5-9 years",  5L,
  "10-14 years", 10L,
  "15-19 years", 15L,
  "20-24 years", 20L,
  "25-29 years", 25L,
  "30-34 years", 30L,
  "35-39 years", 35L,
  "40-44 years", 40L,
  "45-49 years", 45L,
  "50-54 years", 50L,
  "55-59 years", 55L,
  "60-64 years", 60L,
  "65-69 years", 65L,
  "70-74 years", 70L,
  "75-79 years", 75L,
  "80-84", 80L,
  "85-89", 85L,
  "90-94", 90L,
  "95+ years", 95L
)

Introduction

Our objective is to construct a decision model using data and parameters from the 2019 Global Burden of Disease study.

We will consider three methods:

  1. A Markov Trace-Based approach that separately tracks deaths from disease and from other non-disease-related causes, and uses differences in disease-related deaths across cycles to calculate years of life lost to disease (YLLs).
  2. A Transition States approach that is similar to Markov trace approach, but that draws on a death tracking state to calculate YLLs.
  3. A Markov Chain with Rewards approach to Healthy Longevity as developed in Caswell and Zarulli (2018) and Caswell and van Daalen (2021).

Our model will be flexibly parameterized such that practitioners can draw on the provided code to model any disease or country/region represented in the GBD data. For our purposes here, however, we will focus on a general cardiovascular disease model for the United Kingdom. We will also focus on a model for the full population—though the GBD data also allow us to separately model mortality and disease-specific incidence and death separately for males and females.

A state (“bubble”) diagram of the basic model structure is provided in Figure 1:

Figure 1: State Diagram for Cardiovascular Disease Model
life_table_year = 2019 
location = "United Kingdom"
cause_id = 491 # CVD
sex = "Both"
radix = 100000  # Population basis for the construction of life tables

Data Sources

As noted above, all data and parameters (unless assumed) are drawn from the 2019 Global Burden of Disease study. Citations for specific datasets used are provided in Table 1.

Table 1: Data Sources and Citations
Description Source
Life Tables Global Burden of Disease Collaborative Network (2020b)
Disease Incidence Global Burden of Disease Collaborative Network (2020c)
Disease-Related Death Global Burden of Disease Collaborative Network (2020c)
Disease Prevalence by Age Global Burden of Disease Collaborative Network (2020c)
Reference Life Table Global Burden of Disease Collaborative Network (2021)
Disability Weights Global Burden of Disease Collaborative Network (2020a)

Process GBD Data

Construct a Cause-Deleted Life Table

For a disease as prevalent as CVD, it is important that background mortality in our model net out all CVD-related deaths—otherwise, we will overcount CVD deaths, as they would be captured in a separate death-from-CVD rate, and in the background mortality rate.

To construct a cause-deleted life table we will use the GBD query tool to extract an estimate of the percentage of deaths from CVD for various (5-year) age groups. We will then apply this percentage to deaths in the overall life table to obtain an estimate of the number of deaths from CVD. We net this from total deaths and reconstruct the life table using a Multiple Decrements approach.

Life Table Data

The GBD life table data are arranged by age group, so we need to download a separate file for each group, and extract the relevant location and year.

Download and process GBD life table data.
if (!file.exists(here(glue("blog/posts/modeling-dalys/_data/gbd_life_table_{location}-{life_table_year}.rds")))) {
    gbd_life_tables <- c(
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_28_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_5_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_6_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_7_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_8_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_9_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_10_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_11_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_12_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_13_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_14_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_15_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_16_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_17_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_18_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_19_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_20_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_30_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_31_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_32_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_33_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_44_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_45_0.zip",
      "https://ghdx.healthdata.org/sites/default/files/record-attached-files/IHME_GBD_2019_LIFE_TABLES_1950_2019_ID_148_0.zip"
  )
  
  life_table <-
    gbd_life_tables %>% map(~ ({
      cat(glue::glue("File: {.x}\n"))
      tmp <- tempfile()
      tmpdir <- tempdir()
      download.file(.x, tmp)
      nn <-
        gsub(
          "https://ghdx.healthdata.org/sites/default/files/record-attached-files/",
          "",
          .x
        ) %>% gsub(".ZIP|.zip", "", .)
      unzip(tmp)
      ff <- list.files(here(), pattern = ".CSV|.csv")
      lt_age_group <-
        ff[grep("WSHOCK", ff)] %>% map( ~ (read.csv(.x) %>% as_tibble() %>% mutate(file = .x))) %>% pluck(1) %>%
        filter(year_id == life_table_year &
                 location_name == location)
      
      file.remove(ff)
      lt_age_group
    })) %>%
    bind_rows()
  
  lt <-
    life_table %>%
    group_by(location_name, location_id) %>%
    nest()  %>%
    mutate(life_table = map(data,  ~ ({
      .x %>% select(sex_name, age_group_id, age_group_name, measure_name, val) %>%
        mutate(age = age_group_lut[paste0(age_group_id)]) %>% 
        spread(measure_name, val) %>%
        janitor::clean_names() %>%
        rename(ex = life_expectancy,
               qx = probability_of_death) %>%
        arrange(sex_name, age) %>%
        select(sex_name, age, ex, qx) %>%
        gather(measure, value, -sex_name, -age) %>%
        mutate(measure = paste0(measure, gsub("_both", "", paste0("_", sex_name)))) %>%
        select(-sex_name)  %>%
        spread(measure, value) %>%
        mutate(
          p = 1 - qx,
          p_male = 1 - qx_male,
          p_female = 1 - qx_female
        ) %>%
        mutate(
          lx = radix * cumprod(c(1, p[-nrow(.)])),
          lx_male = radix * cumprod(c(1, p_male[-nrow(.)])),
          lx_female = radix * cumprod(c(1, p_female[-nrow(.)]))
        )
    })))

  lt <-
    lt %>%
    mutate(hp_mort = map(life_table,  ~ ({
      ages     <- .x$age
      deaths   <- .x$lx * .x$qx
      exposure <- .x$lx
      
      mort_fit <- MortalityLaw(
        x  = ages,
        Dx  = deaths,
        # vector with death counts
        Ex  = exposure,
        # vector containing exposures
        law = "HP2",
        opt.method = "LF2"
      )
      coef(mort_fit) %>% data.frame() %>% t()
    })))

  lt %>% write_rds(here(glue("blog/posts/modeling-dalys/_data/gbd_life_table_{location}-{life_table_year}.rds")))
  
} 
df_life_table = read_rds(here(glue("blog/posts/modeling-dalys/_data/gbd_life_table_{location}-{life_table_year}.rds")))

The overall life table for our country of interest is shown in Table 2. Relevant columns are described in Table 3.

Construct Overall Life Table
lt <- 
    df_life_table %>% 
    select(location_name,location_id,life_table) %>% 
    unnest(cols = c(life_table))  %>% 
    select(location_name, location_id, age, ex, qx)   %>% 
    mutate(age_diff = c(1,lead(diff(age)))) %>%   # Age difference in age group
    mutate(mx = -log(1 - qx)/age_diff) %>%  # Mortality rate
    select(location_name, location_id, age, ex, qx, mx)  %>% 
    mutate(p = 1 - qx) %>%  # Survival probability
    mutate(cump = ifelse(row_number() == 1, 1, lag(cumprod(p)))) %>% # Cumulative survival
    mutate(lx = radix * cump) %>% # At risk
    mutate(dx = lx * qx) %>% # Deaths = at risk * probability of death
    as.data.table()
setkey(lt, age)

lt %>% select(-location_id) %>% kable(digits = 3) %>% kable_styling()
Table 2: Overall Life Table
location_name age ex qx mx p cump lx dx
United Kingdom 0 81.070 0.004 0.004 0.996 1.000 100000.000 350.925
United Kingdom 1 80.355 0.001 0.000 0.999 0.996 99649.075 59.041
United Kingdom 5 76.401 0.000 0.000 1.000 0.996 99590.034 35.692
United Kingdom 10 71.428 0.000 0.000 1.000 0.996 99554.341 43.338
United Kingdom 15 66.458 0.001 0.000 0.999 0.995 99511.003 120.053
United Kingdom 20 61.535 0.002 0.000 0.998 0.994 99390.950 189.262
United Kingdom 25 56.647 0.002 0.000 0.998 0.992 99201.688 227.279
United Kingdom 30 51.771 0.003 0.001 0.997 0.990 98974.409 311.052
United Kingdom 35 46.926 0.004 0.001 0.996 0.987 98663.357 437.835
United Kingdom 40 42.124 0.007 0.001 0.993 0.982 98225.522 669.101
United Kingdom 45 37.394 0.010 0.002 0.990 0.976 97556.421 984.145
United Kingdom 50 32.748 0.015 0.003 0.985 0.966 96572.276 1489.166
United Kingdom 55 28.219 0.024 0.005 0.976 0.951 95083.110 2312.887
United Kingdom 60 23.856 0.039 0.008 0.961 0.928 92770.223 3601.522
United Kingdom 65 19.712 0.060 0.012 0.940 0.892 89168.701 5376.422
United Kingdom 70 15.805 0.098 0.021 0.902 0.838 83792.279 8207.582
United Kingdom 75 12.233 0.160 0.035 0.840 0.756 75584.698 12084.596
United Kingdom 80 9.055 0.270 0.063 0.730 0.635 63500.101 17118.564
United Kingdom 85 6.434 0.433 0.113 0.567 0.464 46381.538 20064.172
United Kingdom 90 4.426 0.637 0.202 0.363 0.263 26317.366 16755.052
United Kingdom 95 3.100 0.799 0.320 0.201 0.096 9562.313 7636.243
United Kingdom 100 2.226 0.904 0.469 0.096 0.019 1926.070 1741.274
United Kingdom 105 1.720 0.956 0.623 0.044 0.002 184.796 176.607
United Kingdom 110 1.452 1.000 0.000 0.000 8.189 8.189
Table 3: Life Table Parameters
Parameter Description
ex Remaining life expectancy
qx Probability of death in age group
mx Death rate in age group
p Survival probability (1-qx)
cump Cumulative survival probability
lx Number at risk (set at the radix parameter value for the first age group)
dx Number of deaths in age group

Note the life expectancy at age 0 (ex in the table). We’ll come back to this later, when we benchmark life expectancy in our model vs. the life table value.

GBD Cause of Death and Disease Incidence Data

To construct cause-deleted life tables we need an estimate of the number of deaths (dx) due to CVD. And to model transitions from the Healthy state to the CVD health state we’ll need disease incidence rates. To obtain these data we’ll draw on the GBD data tool to extract the percentage of deaths due to CVD, and the CVD incidence rate.1

1 Note you need an account with login and password to download these data.

The specific data query used for this example is provided in Figure 2, and the specific cause-of-death percentages for the country/region of interest are shown in Table 4 and Table 5. Code for constructing the cause-deleted life table will be provided later in this document.

(a) Cause of Death
(b) Age Ranges
Figure 2: Global Burden of Disease Data Query Tool
Download and process GBD CVD incidence and cause of death data.
# You can then click on "Download." To obtain the data in the code below,
# I downloaded the .csv file and used the
# [datapasta](https://github.com/MilesMcBain/datapasta) package in R to
# simply copy and paste the values as a table. Alternatively, you could
# just manually load the .csv file.


df_gbd <- 
tibble::tribble(
    ~measure_id, ~measure_name, ~location_id,   ~location_name, ~sex_id, ~sex_name, ~age_id,     ~age_name, ~cause_id,               ~cause_name, ~metric_id, ~metric_name, ~year,        ~val,      ~upper,      ~lower,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",      5L,   "1-4 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.028996032, 0.032271777, 0.024354871,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",      5L,   "1-4 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.035378341, 0.038200527,  0.02982068,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",      5L,   "1-4 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.031923654, 0.033877513,  0.02749347,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",      5L,   "1-4 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 0.450558018, 0.518217768, 0.366558761,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",      5L,   "1-4 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 0.489648455, 0.546394959, 0.415998276,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",      5L,   "1-4 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 0.469612322, 0.520633016, 0.400518019,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",      6L,   "5-9 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.028030375, 0.030218263, 0.025065873,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",      6L,   "5-9 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.034179575, 0.038337972, 0.030031173,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",      6L,   "5-9 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.030684194, 0.032765225, 0.027736481,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",      6L,   "5-9 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 0.223162961, 0.243068851, 0.195925728,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",      6L,   "5-9 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 0.216691535, 0.243515145,  0.18996081,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",      6L,   "5-9 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 0.220004378, 0.236329232, 0.198461094,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",      7L, "10-14 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.039746344, 0.041717485, 0.036621253,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",      7L, "10-14 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.039007566, 0.043057948, 0.035699452,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",      7L, "10-14 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,  0.03942622, 0.041491836, 0.036825279,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",      7L, "10-14 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 0.383598812, 0.405724933,  0.34991092,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",      7L, "10-14 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 0.301487698, 0.333401339, 0.275739379,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",      7L, "10-14 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 0.343507011,  0.36308575, 0.319699847,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",      8L, "15-19 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.040429815, 0.042516915, 0.038634534,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",      8L, "15-19 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.050448817, 0.056212097, 0.047257679,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",      8L, "15-19 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.043765321, 0.046440911, 0.041928954,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",      8L, "15-19 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 1.272151624, 1.340633778, 1.215478459,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",      8L, "15-19 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 0.830116477, 0.926181301, 0.778133659,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",      8L, "15-19 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 1.056297216, 1.122235147, 1.011670449,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",      9L, "20-24 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.047865254, 0.049912826, 0.045757303,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",      9L, "20-24 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.064022359, 0.070540903, 0.060728528,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",      9L, "20-24 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,  0.05241896, 0.055214123, 0.050297559,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",      9L, "20-24 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 2.584733912, 2.705960617, 2.466297393,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",      9L, "20-24 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 1.396334943, 1.540852926, 1.320505171,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",      9L, "20-24 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 1.999067921, 2.108246777, 1.910639006,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     10L, "25-29 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.089939927,  0.09346508, 0.086949806,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     10L, "25-29 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.089152972, 0.094352463,  0.08473271,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     10L, "25-29 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.089703584, 0.092727269, 0.086724818,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     10L, "25-29 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 5.734533296, 5.967850508, 5.529144225,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     10L, "25-29 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 2.476079844, 2.623849325, 2.341002774,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     10L, "25-29 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 4.117495802, 4.260669343, 3.978963164,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     11L, "30-34 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.127257147,  0.13212298, 0.122966034,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     11L, "30-34 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.101388841, 0.105278948, 0.097807228,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     11L, "30-34 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.118479515, 0.122297221, 0.114897896,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     11L, "30-34 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 10.53187361, 10.94789275, 10.15541571,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     11L, "30-34 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  4.35406213, 4.535772035, 4.190158194,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     11L, "30-34 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 7.458822907, 7.697315036, 7.229905553,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     12L, "35-39 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.164731863, 0.169563876, 0.159608872,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     12L, "35-39 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.115825591, 0.120310278,  0.11192131,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     12L, "35-39 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.146787432,  0.15076718, 0.142663671,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     12L, "35-39 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 18.48100716, 19.11206584, 17.88312257,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     12L, "35-39 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 7.595845898, 7.897360424, 7.306437613,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     12L, "35-39 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 13.06167796, 13.43788854, 12.69877405,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     13L, "40-44 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.203159048,  0.20891541, 0.195943858,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     13L, "40-44 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.129206482,  0.13385869,   0.1244222,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     13L, "40-44 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.175222389, 0.180012567, 0.169598709,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     13L, "40-44 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 34.46754982, 35.59363313, 33.10261974,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     13L, "40-44 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  13.3674334, 13.90211799, 12.83885807,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     13L, "40-44 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  23.9408787, 24.62393849, 23.10570335,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     14L, "45-49 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.235022661, 0.241826968, 0.226840899,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     14L, "45-49 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.137040316, 0.141886473, 0.132341184,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     14L, "45-49 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.195843982, 0.201187744, 0.189756704,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     14L, "45-49 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 57.64153172, 59.64549167,  55.4687179,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     14L, "45-49 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 22.06546161,  22.9227553, 21.21789055,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     14L, "45-49 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 39.72241359, 40.94841318, 38.38898409,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     15L, "50-54 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.277583327, 0.283873162, 0.270171622,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     15L, "50-54 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.145665326, 0.150899461,  0.14013874,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     15L, "50-54 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.223082899, 0.228558598,  0.21707824,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     15L, "50-54 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 102.4443991, 105.5930044, 99.34510962,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     15L, "50-54 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  36.9364505, 38.40924932, 35.41764292,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     15L, "50-54 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 69.29273074, 71.26787821, 67.22859058,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     16L, "55-59 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.285271809, 0.291369585, 0.277471527,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     16L, "55-59 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.150177365, 0.155825218,  0.14478974,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     16L, "55-59 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.229861955, 0.235028894, 0.223731529,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     16L, "55-59 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 167.4830541, 172.2242284, 162.1481434,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     16L, "55-59 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 59.90725095,  62.3881737, 57.55691512,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     16L, "55-59 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 113.0734263, 116.0596868, 109.7658926,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     17L, "60-64 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.281151021, 0.287179834, 0.273136951,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     17L, "60-64 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.170456967,  0.17712227,  0.16456188,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     17L, "60-64 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.236307862, 0.241466541, 0.229548522,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     17L, "60-64 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,   268.83905,  276.361035, 259.7994394,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     17L, "60-64 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 107.5466843, 112.1159275,  103.324387,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     17L, "60-64 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 186.9215396, 191.8272762, 181.0862897,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     18L, "65-69 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.278931352, 0.285390185, 0.270097256,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     18L, "65-69 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.189643852, 0.199262556,  0.18169671,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     18L, "65-69 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,  0.24226236, 0.248654952, 0.234632356,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     18L, "65-69 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 419.0918214, 431.4790993, 404.4716545,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     18L, "65-69 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 188.0950489, 198.0374997, 180.4032472,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     18L, "65-69 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 300.4669833,  309.027596, 290.4451193,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     19L, "70-74 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.290219838, 0.297721979,  0.27908183,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     19L, "70-74 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.228546288, 0.241247991, 0.217055247,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     19L, "70-74 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.264132668, 0.270822598, 0.253757269,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     19L, "70-74 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 718.2484425, 740.2576009, 689.8783971,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     19L, "70-74 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 380.8726776, 402.6775444, 361.1707849,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     19L, "70-74 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 542.4055968, 558.3963894,  519.894653,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     20L, "75-79 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.305504066,  0.31501236,  0.28991667,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     20L, "75-79 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.274243167, 0.291526918,   0.2534384,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     20L, "75-79 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.291549172, 0.302042907,   0.2749541,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     20L, "75-79 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  1261.89787, 1304.650375, 1194.426145,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     20L, "75-79 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 787.6159218, 837.4076702, 725.4738778,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     20L, "75-79 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  1007.22694, 1045.701239, 946.8585675,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     25L, "50-69 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.280637165, 0.285934654, 0.273055284,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     25L, "50-69 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.170429973, 0.177027993, 0.164412797,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     25L, "50-69 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.235520163, 0.240311903, 0.229465139,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     25L, "50-69 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 223.4543262, 229.1140273, 216.5032114,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     25L, "50-69 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 91.11203448, 94.94062023, 87.74771187,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     25L, "50-69 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 156.2300101, 159.9320749, 151.8013825,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     28L,     "<1 year",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,  0.00858897, 0.010099315, 0.006696668,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     28L,     "<1 year",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,  0.00848085, 0.010271002, 0.006544871,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     28L,     "<1 year",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.008541898, 0.010077272, 0.006836472,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     28L,     "<1 year",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 3.330450581, 4.156576477, 2.485530865,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     28L,     "<1 year",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 2.655721293, 3.332256697, 1.951722168,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     28L,     "<1 year",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 3.001802716, 3.744109822, 2.265385428,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     30L,       "80-84",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.323863277, 0.338597632, 0.294179612,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     30L,       "80-84",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.320968389,  0.34424093, 0.277353832,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     30L,       "80-84",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.322454879, 0.339212536, 0.286007648,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     30L,       "80-84",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 2350.714411, 2464.746783, 2115.530404,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     30L,       "80-84",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  1717.38829, 1845.228956, 1482.945198,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     30L,       "80-84",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 1994.660464,  2104.05733, 1763.636077,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     31L,       "85-89",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.333006314, 0.353674853, 0.292419986,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     31L,       "85-89",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.355395094, 0.385917974, 0.295950118,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     31L,       "85-89",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.345166391, 0.370659076,  0.29406337,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     31L,       "85-89",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 4259.496089,  4537.70974,  3739.26705,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     31L,       "85-89",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 3505.823065, 3819.445125, 2924.110658,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     31L,       "85-89",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 3802.353716, 4086.741745,   3239.6705,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     32L,       "90-94",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.347012504, 0.373106092, 0.294444394,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     32L,       "90-94",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,   0.3819742, 0.419626054, 0.306253645,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     32L,       "90-94",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.368727066, 0.401142671, 0.302323004,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     32L,       "90-94",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 7531.385885, 8114.087688, 6404.069434,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     32L,       "90-94",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 6853.993141, 7529.937194, 5521.436605,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     32L,       "90-94",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 7081.097512, 7697.566621,  5793.23943,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     41L, "50-74 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.284276872, 0.289881816, 0.275883579,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     41L, "50-74 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,  0.19327508, 0.202233434, 0.185474593,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     41L, "50-74 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.246545226, 0.251873308, 0.239180583,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",     41L, "50-74 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 304.9005627, 312.7897016, 295.3683794,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",     41L, "50-74 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 140.9599264, 147.5119758, 135.1275867,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",     41L, "50-74 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 221.2598346, 226.8003663, 214.2987814,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",    235L,   "95+ years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.354344993, 0.386231837,  0.29265909,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",    235L,   "95+ years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.393392896, 0.434119892, 0.307881158,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",    235L,   "95+ years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.382935248, 0.420279524, 0.303833964,
             1L,      "Deaths",          95L, "United Kingdom",      1L,    "Male",    235L,   "95+ years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 12002.04233, 13078.34657, 9872.784146,
             1L,      "Deaths",          95L, "United Kingdom",      2L,  "Female",    235L,   "95+ years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 12202.06901,  13473.7584, 9504.961774,
             1L,      "Deaths",          95L, "United Kingdom",      3L,    "Both",    235L,   "95+ years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 12151.87861,  13346.9543,  9633.43595,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     25L, "50-69 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.004427021, 0.005078144, 0.003817809,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     25L, "50-69 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.002897491, 0.003307504, 0.002518334,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     25L, "50-69 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.003648131, 0.004144026, 0.003162723,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     25L, "50-69 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 1972.922887, 2183.340769, 1783.151307,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     25L, "50-69 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 1297.746085, 1452.740976, 1159.106723,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     25L, "50-69 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 1629.961478, 1804.956505, 1471.349106,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     28L,     "<1 year",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    2.91e-05,     4.1e-05,    1.94e-05,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     28L,     "<1 year",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,     3.4e-05,    4.83e-05,    2.34e-05,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     28L,     "<1 year",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    3.14e-05,    4.48e-05,    2.14e-05,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     28L,     "<1 year",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  24.9433321, 33.96240142, 17.20782015,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     28L,     "<1 year",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  27.4884571, 37.70959202,  19.4225552,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     28L,     "<1 year",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 26.18301432, 35.92282821, 18.20916589,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     30L,       "80-84",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006985657, 0.008364013, 0.005750184,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     30L,       "80-84",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006563398, 0.007860287, 0.005399195,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     30L,       "80-84",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006751604, 0.008089858,  0.00558803,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     30L,       "80-84",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 4161.213887, 4821.321585, 3586.445187,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     30L,       "80-84",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 3776.346094, 4384.426185, 3238.701183,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     30L,       "80-84",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 3944.842428, 4557.939924,  3413.53611,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     31L,       "85-89",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.007242723, 0.008670361, 0.006080238,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     31L,       "85-89",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006763107,  0.00802545, 0.005733058,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     31L,       "85-89",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006955542, 0.008211624, 0.005897207,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     31L,       "85-89",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 4809.500805, 5599.626169, 4146.960721,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     31L,       "85-89",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 4337.652627, 5022.204185, 3779.822992,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     31L,       "85-89",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  4523.30004, 5241.389845, 3924.282623,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     32L,       "90-94",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.007008438, 0.008388593, 0.005838585,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     32L,       "90-94",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006764404, 0.008053951, 0.005709127,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     32L,       "90-94",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006847976, 0.008131149, 0.005757493,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     32L,       "90-94",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  5153.35834, 6054.284082, 4415.493281,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     32L,       "90-94",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 4794.899993, 5535.925139, 4168.347946,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     32L,       "90-94",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 4915.077627, 5704.042276, 4254.345879,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     41L, "50-74 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,  0.00478628, 0.005371526, 0.004215691,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     41L, "50-74 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.003465161, 0.003938792, 0.003016288,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     41L, "50-74 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.004112838, 0.004618675,    0.003617,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     41L, "50-74 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 2194.428451,  2406.85803, 1993.159002,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     41L, "50-74 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 1585.679788, 1774.225227, 1422.457827,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     41L, "50-74 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  1883.85151, 2073.117622, 1709.401335,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",      5L,   "1-4 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    3.66e-05,    5.08e-05,    2.53e-05,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",      5L,   "1-4 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    4.35e-05,    6.21e-05,    3.07e-05,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",      5L,   "1-4 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    3.98e-05,    5.55e-05,    2.81e-05,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",      5L,   "1-4 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 24.59324904,  32.3236423, 18.14212397,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",      5L,   "1-4 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 26.63263159, 34.91841748, 19.49651583,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",      5L,   "1-4 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 25.58732887, 33.35788704, 18.93808663,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",      6L,   "5-9 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    3.67e-05,    5.34e-05,    2.38e-05,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",      6L,   "5-9 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    3.95e-05,    5.91e-05,    2.59e-05,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",      6L,   "5-9 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    3.81e-05,    5.55e-05,    2.49e-05,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",      6L,   "5-9 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  22.3310297, 29.90118254, 15.75228658,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",      6L,   "5-9 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 22.79052798, 31.18314184, 16.29025681,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",      6L,   "5-9 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  22.5553023, 30.36903203, 16.05870836,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",    235L,   "95+ years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006466182, 0.008113919,  0.00494906,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",    235L,   "95+ years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006717997, 0.008413103, 0.005246113,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",    235L,   "95+ years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006652245, 0.008337733, 0.005160268,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",    235L,   "95+ years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 5178.260058, 6399.752007, 4145.846455,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",    235L,   "95+ years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 5131.479569, 6198.777078, 4184.513358,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",    235L,   "95+ years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 5143.217659, 6229.849414, 4181.774145,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",      7L, "10-14 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    4.67e-05,    6.82e-05,    3.08e-05,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",      7L, "10-14 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    4.09e-05,     6.2e-05,    2.66e-05,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",      7L, "10-14 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    4.39e-05,     6.5e-05,    2.89e-05,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",      7L, "10-14 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 22.87371889, 31.65284084,  16.4573203,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",      7L, "10-14 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 20.23199773, 28.68155445, 14.22015021,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",      7L, "10-14 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 21.58386475, 30.12858466, 15.54645087,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",      8L, "15-19 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    7.22e-05, 0.000104325,    4.85e-05,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",      8L, "15-19 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    5.64e-05,    7.98e-05,    3.84e-05,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",      8L, "15-19 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    6.41e-05,     9.1e-05,    4.37e-05,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",      8L, "15-19 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 34.20250428, 46.12793294, 24.68278487,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",      8L, "15-19 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 29.51771321, 39.71237203, 21.21899829,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",      8L, "15-19 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 31.91482917, 42.67746643, 23.23585145,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",      9L, "20-24 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,  0.00011163, 0.000147235,     8.4e-05,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",      9L, "20-24 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,    9.12e-05, 0.000117658,    6.89e-05,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",      9L, "20-24 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000100777, 0.000131563,    7.71e-05,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",      9L, "20-24 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  54.5951151, 68.64899462, 42.89967879,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",      9L, "20-24 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 51.94509918, 63.09509796, 41.63066082,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",      9L, "20-24 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 53.28913602, 65.48823937, 42.45328627,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     10L, "25-29 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000158707, 0.000207095, 0.000117263,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     10L, "25-29 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000136054, 0.000173899, 0.000103402,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     10L, "25-29 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000146489, 0.000188698, 0.000109849,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     10L, "25-29 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 76.70838862, 93.77250984, 60.39124664,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     10L, "25-29 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 78.03707895, 94.15243505, 62.22901138,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     10L, "25-29 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 77.36776342, 94.19699663, 61.29602546,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     11L, "30-34 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000236315, 0.000300063, 0.000183309,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     11L, "30-34 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000168815, 0.000212039, 0.000129666,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     11L, "30-34 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000200002, 0.000251883,  0.00015506,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     11L, "30-34 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 114.2120994, 133.3595391, 95.66979032,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     11L, "30-34 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 95.90878029, 112.3761348, 79.98772686,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     11L, "30-34 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 105.1074144,  122.658906, 88.44256099,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     12L, "35-39 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000347394, 0.000453312, 0.000270394,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     12L, "35-39 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000193038, 0.000245021, 0.000153326,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     12L, "35-39 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000265664, 0.000339163, 0.000209296,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     12L, "35-39 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 167.1175818, 202.0579812, 138.5905463,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     12L, "35-39 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 105.3475316, 124.0452099,  89.9565812,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     12L, "35-39 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 136.3645016, 162.6483674, 115.1871198,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     13L, "40-44 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000835388, 0.001023785, 0.000655528,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     13L, "40-44 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000603191, 0.000738318, 0.000478687,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     13L, "40-44 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000713624, 0.000864301, 0.000569002,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     13L, "40-44 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 384.8955549, 434.9926458, 338.5765355,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     13L, "40-44 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 307.5936835, 349.2217189, 267.4334345,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     13L, "40-44 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 346.3302996, 388.3935502, 306.5318635,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     14L, "45-49 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.001508699, 0.001919095, 0.001135102,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     14L, "45-49 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000807068, 0.001040227,  0.00061275,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     14L, "45-49 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.001140713, 0.001440407, 0.000876251,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     14L, "45-49 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 664.2277732, 785.5254694, 550.7914263,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     14L, "45-49 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,  386.048847, 474.1180626, 314.1720448,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     14L, "45-49 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 524.1133361,  619.976481, 437.6751311,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     15L, "50-54 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.002633258, 0.003203164, 0.002128852,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     15L, "50-54 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.001326599,  0.00163697, 0.001070251,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     15L, "50-54 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,   0.0019557,  0.00239358, 0.001601614,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     15L, "50-54 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L,   1140.2292, 1286.609938, 999.7682213,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     15L, "50-54 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 603.6877022, 695.1201457,  518.048283,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     15L, "50-54 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 868.7011461, 979.7466799, 763.2998709,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     16L, "55-59 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.004204248, 0.005237554, 0.003290237,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     16L, "55-59 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.002204806, 0.002739343, 0.001726623,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     16L, "55-59 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.003187612, 0.003910492, 0.002515045,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     16L, "55-59 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 1804.405504, 2137.561767, 1516.901006,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     16L, "55-59 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 956.2414154, 1139.293354, 792.3649777,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     16L, "55-59 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 1375.421559, 1618.977162, 1154.786978,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     17L, "60-64 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.005447639, 0.006505564, 0.004396856,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     17L, "60-64 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.003639274, 0.004311934, 0.002988642,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     17L, "60-64 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.004538721,  0.00539902, 0.003725753,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     17L, "60-64 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 2394.559222, 2706.417654, 2122.400887,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     17L, "60-64 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 1565.638269, 1778.970591, 1380.985421,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     17L, "60-64 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 1973.565082, 2231.553114, 1752.133146,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     18L, "65-69 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006009328, 0.007365994, 0.004737917,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     18L, "65-69 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.005129966, 0.006403949, 0.004026852,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     18L, "65-69 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.005564837, 0.006856215, 0.004415209,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     18L, "65-69 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 2908.778347, 3387.432236, 2421.804073,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     18L, "65-69 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 2402.344734, 2879.709168, 1958.743969,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     18L, "65-69 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 2648.707158, 3117.504164, 2198.479731,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     19L, "70-74 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006372452, 0.007564146, 0.005124882,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     19L, "70-74 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.005920085, 0.007032463, 0.004847155,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     19L, "70-74 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006140623, 0.007282752, 0.004987772,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     19L, "70-74 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 3318.591571, 3781.522952, 2836.207168,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     19L, "70-74 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 2971.474942,  3406.04759, 2572.284332,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     19L, "70-74 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 3137.671712, 3587.877828, 2728.823411,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     20L, "75-79 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006725001, 0.008257301, 0.005419978,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     20L, "75-79 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006329174, 0.007735237, 0.005093644,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     20L, "75-79 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.006515635, 0.007885192, 0.005288763,
             6L,   "Incidence",          95L, "United Kingdom",      1L,    "Male",     20L, "75-79 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 3661.648917, 4282.318944, 3098.287225,
             6L,   "Incidence",          95L, "United Kingdom",      2L,  "Female",     20L, "75-79 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 3327.243918, 3900.027926, 2789.070287,
             6L,   "Incidence",          95L, "United Kingdom",      3L,    "Both",     20L, "75-79 years",      491L, "Cardiovascular diseases",         3L,       "Rate", 2019L, 3482.086459, 4048.435372, 2933.525299
    )
GBD Cause of Death (CVD) Data Table
df_gbd %>% 
  filter(sex_name=="Both") %>% 
  filter((measure_name=="Deaths" & metric_name=="Percent")) %>% 
  mutate(age_name= factor(age_name,levels=lut_age_incidence$age_name)) %>% arrange(age_name) %>% 
  filter(!is.na(age_name))  %>% 
  select(-location_id,-sex_id,-sex_name,-age_id,-cause_id,-metric_id,-location_name,-cause_name,-measure_name,-measure_id,-year) %>% 
  kable(digits = 3) %>% 
  kable_styling()
Table 4: GBD Cause-of-Death Data
age_name metric_name val upper lower
<1 year Percent 0.009 0.010 0.007
1-4 years Percent 0.032 0.034 0.027
5-9 years Percent 0.031 0.033 0.028
10-14 years Percent 0.039 0.041 0.037
15-19 years Percent 0.044 0.046 0.042
20-24 years Percent 0.052 0.055 0.050
25-29 years Percent 0.090 0.093 0.087
30-34 years Percent 0.118 0.122 0.115
35-39 years Percent 0.147 0.151 0.143
40-44 years Percent 0.175 0.180 0.170
45-49 years Percent 0.196 0.201 0.190
50-54 years Percent 0.223 0.229 0.217
55-59 years Percent 0.230 0.235 0.224
60-64 years Percent 0.236 0.241 0.230
65-69 years Percent 0.242 0.249 0.235
70-74 years Percent 0.264 0.271 0.254
75-79 years Percent 0.292 0.302 0.275
80-84 Percent 0.322 0.339 0.286
85-89 Percent 0.345 0.371 0.294
90-94 Percent 0.369 0.401 0.302
95+ years Percent 0.383 0.420 0.304
CVD Incidence Rate (per 100k population) Data Table
df_gbd %>% 
  filter(sex_name=="Both") %>% 
  filter((measure_name=="Incidence" & metric_name=="Rate")) %>% 
  mutate(age_name= factor(age_name,levels=lut_age_incidence$age_name)) %>% arrange(age_name) %>% 
  filter(!is.na(age_name))  %>% 
  select(-location_id,-sex_id,-sex_name,-age_id,-cause_id,-metric_id,-location_name,-cause_name,-measure_name,-measure_id,-year) %>% 
  kable(digits = 3) %>% 
  kable_styling()
Table 5: GBD CVD Incidence Rate Data
age_name metric_name val upper lower
<1 year Rate 26.183 35.923 18.209
1-4 years Rate 25.587 33.358 18.938
5-9 years Rate 22.555 30.369 16.059
10-14 years Rate 21.584 30.129 15.546
15-19 years Rate 31.915 42.677 23.236
20-24 years Rate 53.289 65.488 42.453
25-29 years Rate 77.368 94.197 61.296
30-34 years Rate 105.107 122.659 88.443
35-39 years Rate 136.365 162.648 115.187
40-44 years Rate 346.330 388.394 306.532
45-49 years Rate 524.113 619.976 437.675
50-54 years Rate 868.701 979.747 763.300
55-59 years Rate 1375.422 1618.977 1154.787
60-64 years Rate 1973.565 2231.553 1752.133
65-69 years Rate 2648.707 3117.504 2198.480
70-74 years Rate 3137.672 3587.878 2728.823
75-79 years Rate 3482.086 4048.435 2933.525
80-84 Rate 3944.842 4557.940 3413.536
85-89 Rate 4523.300 5241.390 3924.283
90-94 Rate 4915.078 5704.042 4254.346
95+ years Rate 5143.218 6229.849 4181.774

Parameterize Model

Our next step is to parameterize the model. Note that for the matrix calculus method (Approach 3) we need to separately track transient (Healthy, CVD) and absorbing (background mortality, cause-specific mortality) health states, so we do that in the parameters here.

We will structure our model to consider outcomes under four different strategies:

  1. A natural history model that captures the status quo.
  2. A prevention strategy that reduces CVD incidence.
  3. A treatment strategy that reduces CVD-related death.
  4. A prevention and treatment strategy that combines (2) and (3) above.
# Parameterize

params <- list(
    # Treatment Strategies
    tx_names = c("natural_history","prevent","treat","prevent_treat"),      # treatment names
    n_tx = 4, # number of treatment strategies
    
    tr_names = c("Healthy","CVD"), # transient health states
    ab_names = c("DeathOC","DeathCVD"), # absorbing health states
    n_states = 4, # total number of health states
    
    df_gbd = df_gbd,  # disease incidence and cause-of-death data
    life_table = lt,  # overall life table
    
    horizon = 120,    # model time horizon (in years)  
    r_ann = 1e-6,     # annual discount rate
    Delta_t = 1,      # time step (1 = yearly, 1/12 = monthly, etc.)
    age0 = 0,         # initial age in model
    s0T = c(1,0,0,0), # initial state occupancy  
                      # c(1,0,0,0) means the modeled cohort starts off heatlhy
    
    uCVD = 0.773,     # CVD utility payoff value
    uD = 0,           # Death utility payoff value
    uH = 1,           # Heatlhy utility payoff  value
    
    dw = 0.041,       # CVD disability weight
    
    c_H = 0,
    c_Prevent = 10,   # Cycle cost of prevention strategy 
    c_Treat = 500,    # Cycle cost of treatment strategy
    c_CVD = 500,      # Cycle cost of CVD health state
    c_DeathCVD = 25000, # Transition cost of death from CVD
    
    hr_treat = 0.85,  # Hazard Ratio for Treatment Strategy
    hr_prevent = 0.9, # Hazard Ratio for Prevention Strategy
    
    # GBD Calibration parameters (helps calibrate to reported prevalence by age)
    rr_deathCVD = 1.1,  
    rr_incidence = 0.75,
    
    cycle_correction = "half-cycle",
    
    ExR =  # Reference life table from GBD
      tibble::tribble(
          ~Age, ~Life.Expectancy,
          0L,       88.8718951,
          1L,      88.00051053,
          5L,      84.03008056,
          10L,      79.04633476,
          15L,       74.0665492,
          20L,      69.10756792,
          25L,      64.14930031,
          30L,       59.1962771,
          35L,      54.25261364,
          40L,      49.31739311,
          45L,      44.43332057,
          50L,      39.63473787,
          55L,      34.91488095,
          60L,      30.25343822,
          65L,      25.68089534,
          70L,      21.28820012,
          75L,      17.10351469,
          80L,      13.23872477,
          85L,      9.990181244,
          90L,      7.617724915,
          95L,      5.922359078
      )
)

params <- 
    with(params,{
        modifyList(params,list(
            omega = horizon/Delta_t,  # Total number of cycles
            r_Delta_t = r_ann * Delta_t,  # Cycle discount rate
            ages = (0:(horizon/Delta_t))*Delta_t + age0,  # Age in each cycle
             # Approximation function for reference life table life expectancies:
            fExR = function(x) pmax(0,unname(Hmisc::approxExtrap(ExR$Age, ExR$Life.Expectancy,xout = x)$y))
        ))
    })


# First cycle will be 1,0,0,0 so need to slice off one age for 
# construction of transition matrices, but leave one
# for the trace.
params$ages_trace <- params$ages
params$ages <- params$ages[-length(params$ages)]

Define Functions for Time Inhomogeneous Parameters

Nearly all health state progression parameters in our model are age-depdendent. We therefore need to define functions for each transition rate that are a function of the age of the cohort in the cycle. The functions below draw on the GBD data above to estimate age-specific transition rates for the following transitions:

  • rH_CVD(age) = Healthy to CVD (uses a slightly calibrated GBD disease incidence rate).
  • rCVD_D(age) = CVD to death from CVD (uses the cause-specific mortality rate from a cause-deleted life table).
  • rD(age) = Death from other causes (uses cause-deleted mortality rate from a cause-deleted life table).

For this model, we will simply draw rates directly from the GBD life tables and other data. A limitation of this approach is that ages are grouped into five-year buckets—meaning that the mortality rate will be held constant within an age group.

Age-dependent incidence rate function
rH_CVD <- function(aa,gg = "Both") {
  df_gbd %>% 
    filter(measure_name == "Incidence" & sex_name==gg & metric_name=="Rate") %>% 
    inner_join(lut_age_incidence,"age_name") %>% 
    select(age, cvd_incidence = val) %>% 
    arrange(age) %>% 
    mutate(age_diff = c(1,lead(diff(age)))) %>% 
    mutate(age_diff = ifelse(age==95,5,age_diff)) %>% 
    mutate_at(vars(contains("incidence")),function(x) x) %>% 
    as.data.table() %>% 
    mutate(cvd_incidencepop = cvd_incidence / 100000) %>% 
    setkey(.,age) %>% 
    {.[data.table(age=aa) %>% setkey(.,age),roll="nearest"]} %>% 
    pull(cvd_incidencepop) %>% 
    {. * params$rr_incidence}
}

Optional: Parametric Mortality

As an alternative option that provides age-specific (i.e., ungrouped) rates, we also include a parametric morality model (based on the Heligman-Pollard model, which captures mortality across ages quite well).2

2 To explore more on parametric mortality modeling, see our interactive tutorial here.

The leftmost panel in Figure 3 shows the observed vs. fitted log(mortality rate) for our population, while the rightmost panel shows the residual. The residuals show clearly that the model fits mortality rates well up until about age 80, at which point the modeled mortality rate overstates the death rate until roughly age 95—after which the modeled mortality rate is well below the observed rate.

In the code below, we provide alternative functions to draw on the modeled mortality rates to return age-specific death transition rates—though note that in our results below, we continue to draw directly off the GBD data.

Fit Parametric Mortality Model
fit_mort <- function(params, mortality_model = "HP2", gg = "Both", outcome = "dx_nocvd") {
    with(params,({
        
        pct_cvd <-
            df_gbd %>%
            filter(measure_name == "Deaths" & sex_name == gg & metric_name=="Percent") %>%
            inner_join(lut_age_incidence, "age_name") %>%
            select(
                age,
                pct_cvd = val,
                upper_pct_cvd = upper,
                lower_pct_cvd = lower
            ) %>%
            as.data.table() %>% 
            arrange(age)
        setkey(pct_cvd, age)
        
        lt_cvd <-
            pct_cvd[lt, roll = "nearest"] %>%
            as_tibble() %>%
            mutate(age_diff = c(1,diff(age))) %>% 
            mutate(dx_cvd = (lx * qx * pct_cvd)/age_diff) %>%
            mutate(dx_nocvd  = (dx - dx_cvd)/age_diff) %>% 
            mutate(dx = lx * qx / age_diff) %>% 
            na.omit() 
        
        ages = lt_cvd$age
        deaths = unname(unlist(lt_cvd[,outcome]))
        exposure = lt_cvd$lx
        
        fit_hp <- 
            MortalityLaw(
                x  = ages,
                Dx  = deaths,
                # vector with death counts
                Ex  = exposure,
                # vector containing exposures
                law = "HP2",
                opt.method = "LF2"
            )
        
        return(fit_hp)
    }))
}
Fit and Plot Heligman-Pollard Model
fit_hp = params %>% fit_mort(outcome = "dx") 
plot(fit_hp)
Figure 3: Fitted vs. Observed Mortality Using Heligman-Pollard Parametric Mortality Model
Update parameters with Heligman-Pollard models for CVD deaths and non-CVD deaths.
params <- modifyList(params,{
    list(
        mort_fit_dx = params %>% fit_mort(outcome = "dx") %>% coef(.), 
        mort_fit_dx_nocvd = params %>% fit_mort(outcome = "dx_nocvd")  %>% coef() , 
        mort_fit_dx_cvd = params %>% fit_mort(outcome = "dx_cvd")  %>% coef()
    )
})

disc = 
  exp(-params$r_Delta_t * 0:(params$omega))
Age-dependent mortality rate function
rD <- function(aa, gg = "Both") {
  setkey(lt, age)
  
  pct_cvd <-
      df_gbd %>%
      filter(measure_name == "Deaths" & sex_name == gg & metric_name=="Percent") %>%
      inner_join(lut_age_incidence, "age_name") %>%
      select(
          age,
          pct_cvd = val,
          upper_pct_cvd = upper,
          lower_pct_cvd = lower
      ) %>%
      as.data.table() %>% 
      arrange(age) %>% 
    mutate(pct_cvd = params$rr_deathCVD * pct_cvd)
  setkey(pct_cvd, age)
  
  lt_cvd_ <-
      pct_cvd[lt, roll = "nearest"] %>%
      as_tibble() 
  lt_cvd <- 
      lt_cvd_ %>% 
      #mutate(pct_cvd = 0) %>% 
      mutate(dx_cvd = lx * qx * pct_cvd) %>%
      mutate(dx_nocvd  = dx - dx_cvd,
             R_nocvd = (dx - dx_cvd) / dx) %>%
      mutate(mx_nocvd = R_nocvd * mx,
             mx_cvd = mx - mx_nocvd) %>%
      na.omit() 

  r <-
    lt_cvd %>%
    as.data.table() %>%
    setkey(., age) %>%
    {
        .[data.table(age = aa) %>% setkey(., age), roll = "nearest"]
    } %>%
    pull(mx_nocvd)

  return(r)
}

rCVD_D <- function(aa, gg = "Both") {
setkey(lt, age)
  
  pct_cvd <-
      df_gbd %>%
      filter(measure_name == "Deaths" & sex_name == gg & metric_name=="Percent") %>%
      inner_join(lut_age_incidence, "age_name") %>%
      select(
          age,
          pct_cvd = val,
          upper_pct_cvd = upper,
          lower_pct_cvd = lower
      ) %>%
      as.data.table() %>% 
      arrange(age) %>% 
      mutate(pct_cvd = params$rr_deathCVD * pct_cvd)
  setkey(pct_cvd, age)
  
  lt_cvd_ <-
      pct_cvd[lt, roll = "nearest"] %>%
      as_tibble() 
  lt_cvd <- 
      lt_cvd_ %>% 
      mutate(dx_cvd = lx * qx * pct_cvd) %>%
      mutate(dx_nocvd  = dx - dx_cvd,
             R_nocvd = (dx - dx_cvd) / dx) %>%
      mutate(mx_nocvd = R_nocvd * mx,
             mx_cvd = mx - mx_nocvd) %>%
      na.omit() 

  r <-
    lt_cvd %>%
    as.data.table() %>%
    setkey(., age) %>%
    {
        .[data.table(age = aa) %>% setkey(., age), roll = "nearest"]
    } %>%
    pull(mx_cvd)

  return(r)
  
}

rD_unadj_p = function(aa,params) {
    with(params,{
         coef_ <- mort_fit_dx
        HP2(aa,coef_)$hx   
    })
}

rD_p = function(aa,params) {
      with(params,{
         coef_ <- mort_fit_dx_nocvd
        HP2(aa,coef_)$hx   
    })
}

rCVD_D_p = function(aa,params) {
      with(params,{
         coef_ <- mort_fit_dx_cvd
        HP2(aa,coef_)$hx   
    })
}

Using the functions defined above, we can easily extract transition rates for a given age. Echoing the comments above, note that the basic function (rD(age)) uses grouped mortality rate data, whereas the function based on the Heligman-Pollard model yields different rates for each age:

# Rate of non-cause death for a 75 and 76 year-old
rD(75)
[1] 0.02366835
rD(76)
[1] 0.02366835
# Rate of non-cause death for a 75 and 76 year-old based on Heligman Pollard model
rD_p(75, params = params)
[1] 0.02761481
rD_p(76, params = params)
[1] 0.03007687

Approach 1: Markov Trace

With the basic parameters and parameter functions defined, we can now move to our first approach. Under this approach, we will separate cause-specific and non-CVD deaths as separate health states. The updated state transition diagram is shown in Figure 4:

Figure 4: State Transition Diagram for Approach 1

Building out this model structure requires constructing a series of transition probability matrices.

Parameterize Markov Model
params1 <- with(params,modifyList(params,list(
    # Natural History Transition Rate Matrix
    mR = 
      ages %>% map(~({
        mR_nh = 
          matrix(c(
          -(rH_CVD(.x) + rD(.x)), rH_CVD(.x), rD(.x), 0 ,
          0, -(rD(.x)+ rCVD_D(.x)), rD(.x),rCVD_D(.x),
          0,0,0,0,
          0,0,0,0),
          nrow = 4, 
          ncol = 4,
          byrow=TRUE, 
          dimnames = list(c(tr_names,ab_names),
                          c(tr_names,ab_names)
          ))
        
        mR_prevent = 
          matrix(c(
          -(hr_prevent * rH_CVD(.x) + rD(.x)), hr_prevent * rH_CVD(.x), rD(.x), 0 ,
          0, -(rD(.x)+ rCVD_D(.x)), rD(.x),rCVD_D(.x),
          0,0,0,0,
          0,0,0,0),
          nrow = 4, 
          ncol = 4,
          byrow=TRUE, 
          dimnames = list(c(tr_names,ab_names),
                          c(tr_names,ab_names)
          )) 
        
        mR_treat = 
          matrix(c(
          -(rH_CVD(.x) + rD(.x)), rH_CVD(.x), rD(.x), 0 ,
          0, -(rD(.x)+ hr_treat * rCVD_D(.x)), rD(.x),hr_treat * rCVD_D(.x),
          0,0,0,0,
          0,0,0,0),
          nrow = 4, 
          ncol = 4,
          byrow=TRUE, 
          dimnames = list(c(tr_names,ab_names),
                          c(tr_names,ab_names)
          ))
        
        mR_prevent_treat = 
          matrix(c(
          -(hr_prevent * rH_CVD(.x) + rD(.x)), hr_prevent * rH_CVD(.x), rD(.x), 0 ,
          0, -(rD(.x)+ hr_treat * rCVD_D(.x)), rD(.x),hr_treat * rCVD_D(.x),
          0,0,0,0,
          0,0,0,0),
          nrow = 4, 
          ncol = 4,
          byrow=TRUE, 
          dimnames = list(c(tr_names,ab_names),
                          c(tr_names,ab_names)
          ))
        array(c(as.vector(mR_nh),as.vector(mR_prevent), as.vector(mR_treat),as.vector(mR_prevent_treat)), dim = c(length(tr_names)+ length(ab_names),length(tr_names)+ length(ab_names),length(tx_names)),
          dimnames = list(c(tr_names,ab_names),c(tr_names,ab_names),tx_names)) %>% 
            apply(.,3,function(x) x, simplify=FALSE) 
      }))   
)))

params1 <- with(params1,modifyList(params1,list(
    mP = mR %>% transpose() %>% map(~({
      mR_ = .x
      mR_ %>% map(~({
              expm(.x * Delta_t)
         }))
      })) 
)))

We next draw upon the transition probabilty matrices to create a Markov trace (Table 6):

Calculate Markov Trace
trace1 <- 
    with(params1, {
        mP %>% map( ~ ({
            P = .x
            occ <- s0T
            P %>% map(~({
              occ <<- occ %*% .x
            })) %>% 
            map(~(data.frame(.x))) %>% 
            bind_rows()
        }))
    })  %>% 
    map(~({
        tmp = .x[1,]
        tmp[1,] = params$s0T
        tmp = rbind(tmp,.x)
    }))
tr <- trace1$natural_history
Markov Trace
tr  %>% 
  as_tibble() %>% 
  mutate(age = params$ages_trace)  %>% 
  mutate(cycle = row_number()-1) %>% 
  select(age,cycle,everything()) %>% 
  filter(age %in% lut_age_incidence$age) %>% 
  kable(digits=3) %>% 
  kable_styling()
Table 6: Markov Trace for Approach 1
age cycle Healthy CVD DeathOC DeathCVD
0 0 1.000 0.000 0.000 0.000
1 1 0.996 0.000 0.003 0.000
5 5 0.995 0.001 0.004 0.000
10 10 0.994 0.002 0.004 0.000
15 15 0.992 0.003 0.005 0.000
20 20 0.989 0.004 0.006 0.000
25 25 0.985 0.007 0.008 0.000
30 30 0.980 0.010 0.011 0.000
35 35 0.972 0.014 0.014 0.000
40 40 0.960 0.022 0.018 0.000
45 45 0.939 0.037 0.024 0.000
50 50 0.907 0.059 0.034 0.000
55 55 0.859 0.093 0.047 0.001
60 60 0.790 0.139 0.069 0.001
65 65 0.701 0.194 0.102 0.004
70 70 0.595 0.245 0.151 0.009
75 75 0.481 0.276 0.224 0.019
80 80 0.360 0.270 0.329 0.041
85 85 0.237 0.215 0.470 0.078
90 90 0.126 0.123 0.624 0.127
95 95 0.050 0.043 0.740 0.166

Checkpoint: Overall Survival

Before we proceed, it is useful to stop and check whether the experience of our modeled cohort mirrors the experience of the population as summarized in the GBD input data sources.

In Figure 5 below, we calculate and plot the percent of the cohort surviving at each age (1 - DeathOC - DeathCVD) and overlay the survival probability from the population life table used to parameterize the model. As the figure shows, our modeled cohort nearly exactly matches the survival experience of the population.

Construct Survival Curves
# Check Life Expectancy vs. Life Table
lt_ <- df_life_table %>% 
    select(location_name,location_id,life_table) %>% 
    unnest(cols = c(life_table))  %>% 
    select(location_name, location_id, age, ex, qx)   %>% 
    filter(age >= params1$age0) %>% 
    mutate(age_diff = c(1,lead(diff(age)))) %>% 
    mutate(mx = -log(1 - qx)/age_diff) %>% 
    select(location_name, location_id, age, ex, qx, mx)  %>% 
    mutate(p = 1 - qx) %>%
    mutate(cump = ifelse(row_number() == 1, 1, lag(cumprod(p)))) %>%
    mutate(lx = radix * cump) %>%
    mutate(dx = lx * qx) %>%
    as.data.table()

d_ <- c(1,1,0,0)
as.matrix(tr) %*% d_ %>% data.frame() %>% 
    as_tibble() %>% 
    set_names(c('model')) %>% 
    mutate(age = params$ages_trace) %>% 
    inner_join(lt_ %>% select(age,life_table = cump)) %>% 
    gather(method,value,-age)  %>% 
    ggplot(aes(x = age, y = value)) + geom_line(aes(colour=method)) + 
    theme_ipsum() + 
    geom_dl(method = list("last.points","bumpup"), aes(label = method, colour = method)) + 
    scale_x_continuous(expand = c(.25,0), breaks = seq(0,110,10)) + 
    theme(legend.position="none") + 
    scale_colour_aaas() + 
    labs(x = "Age", y = "Percent Living")
Figure 5: Survival Curve

Checkpoint: CVD Prevalence

Our next checkpoint is designed to assess whether CVD prevalance at any age matches the prevalance value in the GBD data. Figure 6 below shows this using the parameters above.

Note that this

Prevalence by Age, Model vs. GBD Data
df_prevalence <- 
  tibble::tribble(
      ~measure_id, ~measure_name, ~location_id,   ~location_name, ~sex_id, ~sex_name, ~age_id,     ~age_name, ~cause_id,               ~cause_name, ~metric_id, ~metric_name, ~year,        ~val,      ~upper,      ~lower,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",      5L,   "1-4 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,   0.0000878, 0.000129159,   0.0000585,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",      6L,   "5-9 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.001149058, 0.001697486, 0.000762774,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",      7L, "10-14 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.002124186, 0.003148646, 0.001371886,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",      8L, "15-19 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.004583822, 0.006644945, 0.003073985,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",      9L, "20-24 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.005942458, 0.008226115, 0.004300527,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     10L, "25-29 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,  0.00996704, 0.013682815, 0.007414362,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     11L, "30-34 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.011397874, 0.014942621, 0.009118873,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     12L, "35-39 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.014296479, 0.016443542,  0.01252059,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     13L, "40-44 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.037308496, 0.045780893, 0.031435951,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     14L, "45-49 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.051644521, 0.057469379, 0.046823625,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     15L, "50-54 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.078084533, 0.086939447, 0.070462836,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     16L, "55-59 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.120485163, 0.132099872, 0.109649198,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     17L, "60-64 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L,  0.17921163,  0.19685285,  0.16262344,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     18L, "65-69 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.256318787, 0.277513117, 0.236628128,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     19L, "70-74 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.334571503, 0.360158788, 0.307798254,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     20L, "75-79 years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.402821035, 0.432475543, 0.373508479,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     28L,     "<1 year",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.000000668,  0.00000144, 0.000000237,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     30L,       "80-84",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.452174474, 0.483670261, 0.419854319,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     31L,       "85-89",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.472928576, 0.506979294, 0.441347641,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",     32L,       "90-94",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.470160144, 0.508229264, 0.437316163,
               5L,  "Prevalence",          95L, "United Kingdom",      3L,    "Both",    235L,   "95+ years",      491L, "Cardiovascular diseases",         2L,    "Percent", 2019L, 0.448909821, 0.488972286, 0.413508609
      ) %>% 
  inner_join(lut_age_incidence,"age_name") %>% 
  select(age,val)

as.matrix(tr) %>% 
  as_tibble() %>% 
  mutate(age = params$ages_trace) %>% 
  filter(age %in% lut_age_incidence$age)  %>% 
  mutate(prev_model = CVD / (CVD + Healthy)) %>% 
  select(age,prev_model) %>% 
  data.frame() %>% 
  left_join(df_prevalence %>% rename(prev_gbd = val),"age") %>% 
  gather(method,value,-age) %>% 
  ggplot(aes(x = age, y = value, colour = method)) + geom_point() +  geom_line() +
  geom_dl(method=list("last.points","bumpup"),aes(label = method)) +
  theme_ipsum() + 
  scale_colour_aaas() + 
  scale_x_comma(expand = c(0.25,0))
Figure 6: Prevalence by Age, Model vs. GBD Data

Years Lost Due to Disability (YLD)

To calculate YLDs in a given cycle, we multiply state occupancy by a disability weight payoff vector \(\mathbf{d}\),

\[ \mathbf{d}=\left[\begin{array}{c} 0 \\ \text{dw}_{CVD} \big ( \frac{1}{r_{\Delta_t}}(1-e^{-r_{\Delta_t}}) \Delta_t \big ) \\ 0 \\ 0 \end{array}\right] \] where \(\texttt{dwS1}\) and \(\texttt{dwS2}\) are the disability weights for the Sick and Sicker states, respectively.

Years of Life Lost (YLL)

YLLs are based on the present value of remaining life expectancy among deaths that occur in each cycle \(t\). Define \(a(t)\) as the age of the cohort at cycle \(t\), i.e., \(a(t) = t \cdot \Delta t + a0\), where \(a_0\) is the age of the cohort at \(t=0\). Define \(e(t)=e(a(t))\) as the present value of remaining life expectancy at cycle \(t\). Following the GBD continuous time discounting approach, \(e(a(t))\) is given by

\[ e(a(t)) = \frac{1}{r}\big (1 - e^{-rEx(a(t))} \big ) \tag{1}\]

where \(Ex(a)\) is the remaining life expectancy at age \(a\). \(Ex(a)\) is drawn from either an exogenous or an endogenous life table, depending on the objectives of the modeling exercise (Anand and Reddy 2019).

We next define a remaining life expectancy payoff vector at cycle \(t\):

\[ \mathbf{e}(t)=\left[\begin{array}{c} 0 \\ 0 \\ 0 \\ 0 \\ \frac{1}{r}\big (1 - e^{-rEx(a(t))} \big ) \end{array}\right] \]

This payoff vector reflects discounting, but only in terms of the present value of remaining life expectancy at time \(t\).

Calculate Outcomes
# Life Expectancy (Non-Discounted)
le_ = with(params1,(matrix(c(1,
              1 ,
              0,
              0) * Delta_t,
            dimnames = list(c(
                c(tr_names,ab_names)
            ), c("LE")))
))

LEt <- trace1 %>% map( ~ ({
    tmp = as.matrix(.x) %*% le_
    tmp 
}))

LE = LEt %>% map(~sum(.x * gen_wcc(params1$omega, method = params1$cycle_correction))) 


# Life Expectancy (Non-Discounted)
qaly_ = with(params1,(matrix(c(uH,
              uCVD ,
              0,
              0) * Delta_t,
            dimnames = list(c(
                c(tr_names,ab_names)
            ), c("UW")))
))

QALYt <- trace1 %>% map( ~ ({
    tmp = as.matrix(.x) %*% qaly_
    tmp 
}))

QALY = QALYt %>% map(~sum(.x * disc * gen_wcc(params1$omega, method = params1$cycle_correction))) 

# YLD

yld_ = with(params1,(matrix(c(0,
              dw * Delta_t * (1/r_Delta_t) * (1 - exp(-r_Delta_t)) ,
              0,
              0),
            dimnames = list(c(
                c(tr_names,ab_names)
            ), c("DW")))
))

YLDt <- trace1 %>% map( ~ ({
    tmp = as.matrix(.x) %*% yld_
    tmp 
}))

YLD = YLDt %>% map(~sum(.x*  disc * gen_wcc(params1$omega, method = params1$cycle_correction)))

# YLL

new_deaths_from_disease <- 
    map(trace1,~({
        c(0,diff(.x[,"DeathCVD"]))
    })) 
   
remaining_life_expectancy <- 
    with(params1,(1/r_ann) * (1 - exp(-r_ann * fExR(ages_trace))))
    
YLLt <- 
    new_deaths_from_disease %>% map(~(.x * remaining_life_expectancy ))

YLL <- 
    YLLt %>% map(~(sum(.x * disc * gen_wcc(params1$omega,method = params1$cycle_correction))))

DALY <- 
    map2(YLL,YLD,~(.x + .y))

result1 <- cbind(LE, YLD, YLL, DALY) %>%
  as.data.frame() %>%
  mutate_all( ~ as.numeric(.))  %>%
  rownames_to_column(var = "strategy") %>%
  mutate(approach = "Markov Trace") %>%
  mutate(LE_LT = lt %>% filter(age == params1$age0) %>% pull(ex)) %>%
  mutate(LE_LT = ifelse(strategy != "natural_history", NA, LE_LT)) %>%
  dplyr::select(approach, strategy, LE_LT, LE, YLD, YLL, DALY) 

result1 %>% 
    kable(digits = 3, col.names = c("Approach","Scenario","Life Expectancy (Life Table)","Life Expectancy (Model)","YLDs","YLLs","DALYs")) %>% 
    kable_styling()
Approach Scenario Life Expectancy (Life Table) Life Expectancy (Model) YLDs YLLs DALYs
Markov Trace natural_history 81.07 81.081 0.363 1.921 2.284
Markov Trace prevent 81.188 0.334 1.787 2.121
Markov Trace treat 81.255 0.370 1.704 2.074
Markov Trace prevent_treat 81.350 0.341 1.585 1.926

Approach 2: Transition States

Parameterize Transition State Model
params2 <- with(params,modifyList(params,list(
    tr_names = c("Healthy","CVD"), # transient health states
    ab_names = c("Death","trDeathCVD"), # absorbing health states
    n_states = 4
)))

params2 <- with(params2,modifyList(params2,list(
    # Natural History Transition Rate Matrix
    mR = 
      ages %>% map(~({
        
        mR_nh = 
          matrix(c(
          -(rH_CVD(.x) + rD(.x)), rH_CVD(.x), rD(.x), 0 ,
          0, -(rD(.x)+ rCVD_D(.x)), rD(.x) + rCVD_D(.x),rCVD_D(.x),
          0,0,0,0,
          0,0,0,0),
          nrow = 4, 
          ncol = 4,
          byrow=TRUE, 
          dimnames = list(c(tr_names,ab_names),
                          c(tr_names,ab_names)
          ))
        
        mR_prevent = 
          matrix(c(
          -(hr_prevent * rH_CVD(.x) + rD(.x)), hr_prevent * rH_CVD(.x), rD(.x), 0 ,
          0, -(rD(.x)+ rCVD_D(.x)), rD(.x) + rCVD_D(.x),rCVD_D(.x),
          0,0,0,0,
          0,0,0,0),
          nrow = 4, 
          ncol = 4,
          byrow=TRUE, 
          dimnames = list(c(tr_names,ab_names),
                          c(tr_names,ab_names)
          )) 
        
        mR_treat = 
          matrix(c(
          -(rH_CVD(.x) + rD(.x)), rH_CVD(.x), rD(.x), 0 ,
          0, -(rD(.x)+ hr_treat * rCVD_D(.x)), rD(.x) + hr_treat * rCVD_D(.x),hr_treat * rCVD_D(.x),
          0,0,0,0,
          0,0,0,0),
          nrow = 4, 
          ncol = 4,
          byrow=TRUE, 
          dimnames = list(c(tr_names,ab_names),
                          c(tr_names,ab_names)
          ))
        
        mR_prevent_treat = 
          matrix(c(
          -(hr_prevent * rH_CVD(.x) + rD(.x)), hr_prevent * rH_CVD(.x), rD(.x), 0 ,
          0, -(rD(.x)+ hr_treat * rCVD_D(.x)), rD(.x) + hr_treat * rCVD_D(.x),hr_treat * rCVD_D(.x),
          0,0,0,0,
          0,0,0,0),
          nrow = 4, 
          ncol = 4,
          byrow=TRUE, 
          dimnames = list(c(tr_names,ab_names),
                          c(tr_names,ab_names)
          ))
        array(c(as.vector(mR_nh),as.vector(mR_prevent), as.vector(mR_treat),as.vector(mR_prevent_treat)), dim = c(length(tr_names)+ length(ab_names),length(tr_names)+ length(ab_names),length(tx_names)),
          dimnames = list(c(tr_names,ab_names),c(tr_names,ab_names),tx_names)) %>% 
            apply(.,3,function(x) x, simplify=FALSE) 
      }))   
)))

params2 <- with(params2,modifyList(params2,list(
    mP = mR %>% transpose() %>% map(~({
      mR_ = .x
      mR_ %>% map(~({
              tmp = expm(.x * Delta_t)
              tmp["trDeathCVD","trDeathCVD"] = 0
              tmp
         }))
      })) 
)))
Construct Markov Trace
trace2 <- 
    with(params2, {
        mP %>% map( ~ ({
            P = .x
            occ <- s0T
            P %>% map(~({
              occ <<- occ %*% .x
            })) %>% 
            map(~(data.frame(.x))) %>% 
            bind_rows()
        }))
    }) %>% 
    map(~({
        tmp = .x[1,]
        tmp[1,] = params$s0T
        tmp = rbind(tmp,.x)
    }))
Calculate Outcomes Based on Death Transitions
# Life Expectancy (Non-Discounted)
le_ = with(params2,(matrix(c(1,
              1 ,
              0,
              0) * Delta_t,
            dimnames = list(c(
                c(tr_names,ab_names)
            ), c("LE")))
))

LEt <- trace2 %>% map( ~ ({
    tmp = as.matrix(.x) %*% le_
    tmp 
}))

LE2 = LEt %>% map(~sum(.x * gen_wcc(params1$omega, method = params1$cycle_correction))) 

# Life Expectancy (Non-Discounted)
qaly_ = with(params2,(matrix(c(uH,
              uCVD ,
              0,
              0) * Delta_t,
            dimnames = list(c(
                c(tr_names,ab_names)
            ), c("UW")))
))

QALYt <- trace2 %>% map( ~ ({
    tmp = as.matrix(.x) %*% qaly_
    tmp 
}))

QALY2 = QALYt %>% map(~sum(.x * disc * gen_wcc(params1$omega, method = params1$cycle_correction))) 

# YLD

yld_ = with(params2,(matrix(c(0,
              dw * Delta_t * (1/r_Delta_t) * (1 - exp(-r_Delta_t)) ,
              0,
              0),
            dimnames = list(c(
                c(tr_names,ab_names)
            ), c("DW")))
))


YLDt <- trace2 %>% map( ~ ({
    tmp = as.matrix(.x) %*% yld_
    tmp 
}))

YLD2 = YLDt %>% map(~sum(.x*  disc * gen_wcc(params1$omega, method = params1$cycle_correction)))

# YLL
Ex <- matrix(0,ncol= 4, nrow = params2$omega+1)
Ex[,4] =  with(params1,(1/r_ann) * (1 - exp(-r_ann * fExR(ages_trace))))

YLLt <- 
    trace2 %>% map(~({
      .x * Ex
    }))

YLL2 <- 
    YLLt %>% map(~(sum(.x * disc * gen_wcc(params1$omega,method = params1$cycle_correction))))

DALY2 <- 
    map2(YLL2,YLD,~(.x + .y))

result2 <- cbind(LE2, YLD2,YLL2,DALY2) %>%
    as.data.frame() %>%
    mutate_all(~as.numeric(.))  %>%
    rownames_to_column(var="strategy") %>%
    mutate(approach = "Transition States") %>%
    dplyr::select(approach, strategy, LE = LE2, YLD=YLD2, YLL=YLL2, DALY=DALY2)

tib <- result1 %>%
    bind_rows(result2)

tib %>%
    arrange(strategy) %>%
    select(-strategy) %>%
    kable(digits = 3, col.names = c("Approach","Life Expectancy (Life Table)","Life Expectancy (Model)","YLDs","YLLs","DALYs")) %>% 
    kable_styling() %>% 
    pack_rows(index = c("natural_history" = 2, "prevention" = 2, "treatment" = 2,"prevent_treat" = 2)) %>%
    kable_styling()
Approach Life Expectancy (Life Table) Life Expectancy (Model) YLDs YLLs DALYs
natural_history
Markov Trace 81.07 81.081 0.363 1.921 2.284
Transition States 81.081 0.363 1.921 2.284
prevention
Markov Trace 81.188 0.334 1.787 2.121
Transition States 81.188 0.334 1.787 2.121
treatment
Markov Trace 81.350 0.341 1.585 1.926
Transition States 81.350 0.341 1.585 1.926
prevent_treat
Markov Trace 81.255 0.370 1.704 2.074
Transition States 81.255 0.370 1.704 2.074

Approach 3: Healthy Longevity (Markov Chain with Rewards)

This approach adapts the protocol in Caswell and van Daalen (2021) to calculate, YLL, YLD, and DALY outcomes using a Markov chain with rewards. The approach is quite math-heavy—though the code provided below is generalized enough that it can be adapted for nearly any decision analytic model.

The healthy longevity method proposed by Caswell and van Daalen (2021) Caswell and Zarulli (2018) are quite powerful, allowing for estimation of expected values as well as other higher-level moments in an outcome distribution (e.g., variance, skewness, etc.). To keep exposition as simple as possible, we focus here only on expected values—though note that formulas for calculating other moments can be found in the original studies.

Define

\[ \begin{aligned} \tau &= \text{Number of transient (non-absorbing) states}\\ \alpha &= \text{Number of absorbing states}\\ \omega &= \text{Number of cycles} \\ s &= \text{Total number of states; }s=\tau\omega+\alpha \\ \mathbf{U}_{x} &= \text{Transition matrix for age }x, \text{for }x=1,\dots,\omega\\ \mathbf{D}_{j} &=\text{Age advancement matrix for stage }j, \text{for }j=1,\dots,\tau \\ \mathbf{M}_{i} &= \text{Mortality matrix for age class }x, \text{for } x = 1,\dots\omega \\ \mathbf{K} &= \text{vec-permutation matrix; parameters }\tau,\omega \end{aligned} \]

In the above notation, the matrix \(\mathbf{U}_x\) captures transition probabilities among transient (i.e., non-absorbing) health states, while \(\mathbf{M}_x\) captures transitions from transient health states to the absorbing death states (non-CVD mortality and CVD-mortality). Indexing by age class \(x\) indicates that separate matrices are defined for each age in the Markov model—that is, our Markov model is time inhomogeneous.

To construct \(\mathbf{U}_x\) and \(\mathbf{M}_x\) we define transition rate (“intensity”) matrices as in Approaches 1 and 2 above.3 The overall intensity matrix \(\mathbf{Q_x}\) is given by

3 The only difference with the two approaches above is that the rows in these rate matrices correspond to the final state, while the columns correspond to the starting state; this is the opposite of the rate matrices defined above, where the rows corresponded to the starting health state and the columns to the ending health state in a given cycle.

\[ \mathbf{Q}_x=\left(\begin{array}{c|c} \mathbf{V}_x & \mathbf{0} \\ \hline \mathbf{S}_x & \mathbf{0} \end{array}\right) \] where \(\mathbf{V}_x\) is the rate matrix for the transitory (i.e., non-absorbing) states and \(\mathbf{S}_x\) is the rate matrix for the absorbing states. The diagonal elements of \(\mathbf{Q}_x\) are the negative sum of the non-diagonal column elements, thus making the column sums of \(\mathbf{Q}_x\) zero.

For the defined time step \(\Delta_t\), the discrete time transition probability matrix \(\mathbf{P}_x\) is obtained by taking the matrix exponential of the intensity matrix (\(\mathbf{Q}_x\)) multipled by the time step (\(\Delta_t\)):

\[ \mathbf{P}_x =e^{\mathbf{Q}_x \Delta t} \]

We can then obtain \(\mathbf{U}_x\) and \(\mathbf{M}_x\) based on:

\[ \mathbf{P}_x =\left(\begin{array}{c|c} \mathbf{U}_x & \mathbf{0} \\ \hline \mathbf{M}_x & \mathbf{0} \end{array}\right) \]

In addition, the matrix \(\mathbf{D}_j\) defines age advancement in the Markov chain. Using the example from Caswell and van Daalen (2021), if \(\omega=3\) then

\[ \mathbf{D}_j=\left(\begin{array}{ccc} 0 & 0 & 0 \\ 1 & 0 & 0 \\ 0 & 1 & {[1]} \end{array}\right) \quad j=1, \ldots, \tau \]

In our implementation, we include the (optional) 1 value in the lower right corner; this assumes that after the last specified age, the cohort continues to experience transitions among health states according to the transition probabilities defined for the last age class. If this value is 0, the model will assume that everyone dies after the last cycle.

Parameterize the Healthy Longevity Model (Part 1)
params3_ <- with(params,modifyList(params,list(
    alpha = length(ab_names),
    tau = length(tr_names), 
    s = length(tr_names)*omega + length(ab_names) #total number of states;s=τω+α
)))

params3_ <- with(params3_,modifyList(params3_,list(
    # Natural History Transition Rate Matrix
    mR = 
      ages %>% map(~({
        mR_nh = 
          matrix(c(
          -(rH_CVD(.x) + rD(.x)), rH_CVD(.x), rD(.x), 0 ,
          0, -(rD(.x)+ rCVD_D(.x)), rD(.x),rCVD_D(.x),
          0,0,0,0,
          0,0,0,0),
          nrow = 4, 
          ncol = 4,
          byrow=TRUE, 
          dimnames = list(c(tr_names,ab_names),
                          c(tr_names,ab_names)
          ))

        mR_prevent = 
          matrix(c(
          -(hr_prevent * rH_CVD(.x) + rD(.x)), hr_prevent * rH_CVD(.x), rD(.x), 0 ,
          0, -(rD(.x)+ rCVD_D(.x)), rD(.x),rCVD_D(.x),
          0,0,0,0,
          0,0,0,0),
          nrow = 4, 
          ncol = 4,
          byrow=TRUE, 
          dimnames = list(c(tr_names,ab_names),
                          c(tr_names,ab_names)
          )) 
        
        mR_treat = 
          matrix(c(
          -(rH_CVD(.x) + rD(.x)), rH_CVD(.x), rD(.x), 0 ,
          0, -(rD(.x)+ hr_treat * rCVD_D(.x)), rD(.x),hr_treat * rCVD_D(.x),
          0,0,0,0,
          0,0,0,0),
          nrow = 4, 
          ncol = 4,
          byrow=TRUE, 
          dimnames = list(c(tr_names,ab_names),
                          c(tr_names,ab_names)
          ))
        
        mR_prevent_treat = 
          matrix(c(
          -(hr_prevent * rH_CVD(.x) + rD(.x)), hr_prevent * rH_CVD(.x), rD(.x), 0 ,
          0, -(rD(.x)+ hr_treat * rCVD_D(.x)), rD(.x),hr_treat * rCVD_D(.x),
          0,0,0,0,
          0,0,0,0),
          nrow = 4, 
          ncol = 4,
          byrow=TRUE, 
          dimnames = list(c(tr_names,ab_names),
                          c(tr_names,ab_names)
          ))
        array(c(as.vector(mR_nh),as.vector(mR_prevent), as.vector(mR_treat),as.vector(mR_prevent_treat)), dim = c(length(tr_names)+ length(ab_names),length(tr_names)+ length(ab_names),length(tx_names)),
          dimnames = list(c(tr_names,ab_names),c(tr_names,ab_names),tx_names)) %>% 
            apply(.,3,function(x) t(x), simplify=FALSE) 
      }))   
)))

# not sure why this is needed, but otherwise the length gets set too long...
params3 <- with(params3_, modifyList(params3_, list(mR_ = mR %>% transpose())))
params3$mR = params3$mR_

params3 <- with(params3,modifyList(params3,list(
    mV = mR %>% map(~({
            R = .x
            R %>% map(~({
              m <- .x[tr_names,tr_names] 
            }))
            
        })),
     
    mQ = mR %>% map(~({
      R = .x 
      R %>% map(~({
                V = .x[tr_names,tr_names]
                S = .x[ab_names,tr_names]
                zero_ <- matrix(0, nrow = length(tr_names)+length(ab_names), ncol = length(ab_names))
                tmp <- cbind(rbind(V,S),zero_)
                dimnames(tmp) <- list(c(tr_names,ab_names),c(tr_names,ab_names))
                tmp
      }))
    }))    
)))

params3 <- with(params3,modifyList(params3,list(
    mP = mQ %>% map(~({
          Q = .x
          Q %>% map(~(expm(.x * Delta_t)))
    }))
)))

params3 <- with(params3,modifyList(params3,list(
    mU = mP %>% map(~({
          P <- .x 
          P %>% map(~(.x[tr_names,tr_names]))
    })),
    mM = mP %>% map(~({
        P = .x
        P %>% map(~(.x[ab_names,tr_names]))
        
    }))
)))

params3 <- with(params3,modifyList(params3,list(
    D = {
        # Create diagonal age advancement matrix
        D <- matrix(0, omega, omega)
        vec <- rep(1, omega-1)
        D[row(D)-1 == col(D)] <- vec
        D[omega,omega] = 1
        D
    }
)))

We next combine the transition matrices (for all age classes) together into a series of block-structured matrices as follows:

\[ \mathbb{U}=\left(\begin{array}{c|c|c} \mathbf{U}_1 & \cdots & \mathbf{0} \\ \hline & \ddots & \\ \hline \mathbf{0} & \cdots & \mathbf{U}_\omega \end{array}\right) \]

\[ \mathbb{D}=\left(\begin{array}{c|c|c} \mathbf{D}_1 & \cdots & \mathbf{0} \\ \hline & \ddots & \\ \hline \mathbf{0} & \cdots & \mathbf{D}_\tau \end{array}\right) \]

\[ \tilde{\mathbf{U}}=\mathbf{K}^{\top} \mathbb{D} \mathbf{K} \mathbb{U} \quad \tau \omega \times \tau \omega \]

where \(\mathbf{K}\) is a permutation matrix known as the vec-permutation matrix.4 See Henderson and Searle (1981) and Appendix B in Caswell and van Daalen (2021) for further information.

4 A function to construct a vec-permultation matrix is provided within the code snippet below.

We also define

\[ \tilde{\mathbf{M}}=\left(\begin{array}{lll} \mathbf{M}_1 & \cdots & \mathbf{M}_\omega \end{array}\right) \quad \alpha \times \tau \omega \]

and

\[ \tilde{\mathbf{P}}=\left(\begin{array}{c|c} \tilde{\mathbf{U}} & \mathbf{0}_{\tau \omega \times \alpha} \\ \hline \tilde{\mathbf{M}} & \mathbf{I}_{\alpha \times \alpha} \end{array}\right) \quad(\tau \omega+\alpha) \times(\tau \omega+\alpha) \]

Construct block matrices
vec <-  # a simple function to return the vec of an array
    function(x) {
        y <- c(x)
        return(y)
    }

vecperm <- 
    # vecperm
    # function to calculate the vec permutation matrix K of index m,n
    # let X be a m x n matrix, and X' the transpose of X
    # then K satisfies 
    # vec(X') = K*vec(X)
    function(m, n) {
        K <- matrix(0, m * n, m * n)
        a <- matrix(0, m, n)
        
        for (i in 1:m) {
            for (j in 1:n) {
                e <- a
                e[i, j] <- 1
                K <- K + kronecker(e, t(e))
            }
        }
        
        return(K)
    }

params3 <- with(params3,modifyList(params3,list(
    bbD_ = kronecker(diag(tau), D),
    bbU_ =  mU %>% 
            map(~(bdiag(.x))),
    K = vecperm(tau, omega)
)))

params3 <- with(params3,modifyList(params3,list(
    mUtilde = bbU_ %>% map( ~ ({
        t(K) %*% bbD_ %*% K %*% .x
    }))
)))

params3 <- with(params3,modifyList(params3,list(
    mMtilde = mM %>% map(~({
      do.call(cbind,.x) 
    }))  
)))

params3 <- with(params3,modifyList(params3,list(
    mPtilde =  map2(mUtilde, mMtilde,  ~ ({
            rbind(cbind(.x, matrix(0, tau * omega, alpha)) ,
                  cbind(.y, diag(alpha)))
        }))
)))

We now (nearly) have the components needed to calculate outcomes. A key difference in the Healthy Longevity approach, relative to the approaches above, is that we do not calculate outcomes off a trace. Rather, the method utilizes matrix calculus to solve for expected outcomes and other moments in the outcome distribution (e.g., variance, skewness, etc.).5

5 Again, for our purposes here we will focus on expected outcomes—though note that formulas for higher-order moments are provided in Caswell and van Daalen (2021) and Caswell and Zarulli (2018).

To calculate outcomes, we must next define “reward” matrices \(\mathbf{R}_m\), where \(m\) indexes the moment of interest (e.g., expected value, variance, etc.). The structure and values of \(\mathbf{R}_m\) will differ, however, depending on the outcome.

To facilitate how we define rewards (i.e., payoffs), we briefly classify each of our outcomes (LE, YLL, YLD, DALYs, QALYs) into broad classes corresponding to whether the payoff or “reward” applies to occupancy, or to transitions, within or to a given health state:

Classification of Health Outcomes
Outcome Reward Class
Life Expectancy Occupancy (1.0 for each alive health state)
Years of life lived with disability (YLD) Occupancy (disability weight applied to time in CVD state)
Yearls of life lost to disease (YLL) Transition (remaining life expectancy applied to CVD death transitions)
Disability-Adjusted Life Years (DALYs) Occupancy (YLD) + Transition (YLL)
Quality-Adjusted Life Years Occupancy (utility weights applied to living health states)

Occupancy-Based Outcomes

To calculate occupancy-based outcomes, we start with a reward matrix \(\mathbf{H}\), which has dimensions \(\tau \times \omega\) and is structured as shown in Figure 7:

Figure 7: Reward matrix \(\mathbf{H}\)

Cell values within this matrix can be set to one if we want to “reward” that health state-age combination in our outcome measure, and zero otherwise.6

6 This structure allows us, for example, to estimate outcomes for certain age ranges or other decision-relevant combinations of health state and age.

For occupancy-based outcomes, we define \(\mathbf{H}\) such that each cell receives a value of one.

Figure 8: Reward matrix \(\mathbf{H}\)

We use this matrix to define the reward vector \(\mathbf{h}\):7

7 The \(\text{vec}\) operator stacks the columns of an \(m \times n\) matrix into a \(mn \times 1\) vector.

\[ \mathbf{h} = \text{vec } \mathbf{H} \] We also define \(\neg \mathbf{h}\) as the complement of \(\mathbf{h}\), (i.e., values of 1.0 become 0, and vice versa).

Occupancy-based outcomes with partial rewards (e.g., YLDs, QALYs) require an additional matrix \(\mathbf{V}\), which has the same structure as \(\mathbf{H}\):

If \(\mathbf{S}\) is the set of states that receive a reward (e.g., the CVD state for both QALYs and YLDs), then a cycle spent in state \(i\) at age \(j\) is defined by

\[ \mathbf{V}(i, j)= \begin{cases}E\left[v(i, j)\right] & \text { if }(i, j) \in \mathcal{S} \\ 0 & \text { otherwise }\end{cases} \] For YLD outcomes, \(\mathbf{V}\) is defined as shown in Figure 9, while for QALY outcomes \(\mathbf{V}\) is defined as shown in Figure 10 .

Figure 9: Reward matrix for YLD Outcome
Figure 10: Reward matrix for QALY Outcome

We simliarly define an occupancy indicator vector \(\mathbf{v}\) just as we did \(\mathbf{h}\):

\[ \mathbf{v}_{m}=\operatorname{vec} \mathbf{V}_{m} \]

Rewards for Partial Occupancy

Like many health economic applications, the Healthy Longevity approach makes assumptions on partial occupancy in a health state.8 Specifically, the approach assumes that partial occupancy in a health state receives half the reward—essentially, we draw on an assumption that mid-cycle transitions occur at the half-way point.9

8 For example, half-cycle corrections are often used—though there are other methdos (e.g., Simpson’s rule) that are also drawn upon.

9 This is similar to the standard “half-cycle” correction, however under this approach, a half-cycle correction occurs in each cycle, not in the first and last cycles. As we will see below, for rewards that are uniform across transient health states (e.g., calculating life expectancy involves a “payoff” of 1.0 for every living health state) this will yield identical answers as a Markov trace-based approach that adopts a half-cycle correction.

We combine this partial ocupancy assumption, along with the vectorized reward matrices \(\mathbf{h}\) and \(\mathbf{v}\) to obtain the following:

\[ \begin{aligned} \tilde{\mathbf{B}}_{1} & =\mathbf{h} \mathbf{v}_{1}^{\top}+\frac{1}{2}(\neg \mathbf{h})\left(\mathbf{v}_{1}^{\top}\right)+\frac{1}{2}\left(\mathbf{v}_{1}\right)\left(\neg \mathbf{h}^{\top}\right) \\ \end{aligned} \] and

\[ \tilde{\mathbf{C}}_{1}=\frac{1}{2} \mathbf{1}_{\alpha} \mathbf{v_1}^{\top} \]

We combine \(\tilde{\mathbf{B}}_{1}\) and \(\tilde{\mathbf{C}}_{1}\) to obtain:

\[ \tilde{\mathbf{R}}_{1}=\left(\begin{array}{c|c} \tilde{\mathbf{B}}_{1} & \mathbf{0} \\ \hline \tilde{\mathbf{C}}_{1} & \mathbf{0} \end{array}\right) \] which has same block structure as the transition probability matrix \(\tilde{\mathbf{P}}\).

Expected outcomes are based on

\[ \begin{aligned} & \tilde{\boldsymbol{\rho}}_{1}=\tilde{\mathbf{N}}^{\top} \mathbf{Z}\left(\tilde{\mathbf{P}} \circ \tilde{\mathbf{R}}_{1}\right)^{\top} \mathbf{1}_{s} \end{aligned} \] where \(\tilde{\mathbf{N}}\) is the fundamental matrix

\[ \tilde{\mathbf{N}}=(\mathbf{I}-\tilde{\mathbf{U}})^{-1} \] and \(\mathbf{Z}\) is

\[ \mathbf{Z}=\left(\mathbf{I}_{\tau \omega} \mid \mathbf{0}_{\tau \omega \times \alpha}\right) \]

Transition-Based Outcomes

For transition-based outcomes such as YLLs, we define the first moment of remaining life expectancy as the vector \(\tilde{\boldsymbol{\eta}}^{\top}\). This vector has dimensions \(\tau\omega \times 1\) and has the following basic structure:

\[ \tilde{\mathbf{\eta}}=\left(\begin{array}{c} \eta_{11} \\ \vdots \\ \eta_{\tau 1} \\ \hline \vdots \\ \hline \eta_{1 \omega} \\ \vdots \\ \eta_{\tau \omega} \end{array}\right) \] where \(\eta_{i x}\) is remaining life expectancy for an individual in health state \(i\) at a given age \(x\). In this structure, remaining life expectancy for each health state is grouped within age classes.

Our choice for remaining life expectancy values \(\eta_{i x}\) for YLL outcomes will depend on the context and research question at hand (Anand and Reddy 2019). Historically, the GBD has utilized an exogenous, external life table based on the maximum potential life span among humans (Global Burden of Disease Collaborative Network 2021). Anand and Reddy (2019) discuss alternative contexts in which remaining life expectancy based on an endogenous life table or life expectancy model might be preferred.

The distinction between exogenous and endogenous rewards for YLLs boils down to whether the remaining life expectancy value used originates from outside the population under study (i.e., mortality risks used to calculate remaining life expectancy at a given age are independent of the mortality risks of the population being assessed), or not.

For YLLs based on exogenous life tables, such as the reference life table published by the GBD, we define \(\tilde{\boldsymbol{\eta}}^{\top}\) based on the reference life table value at each age. For YLLs based on an endogenous life table, we could simply swap in external life table values from our country or region of interest, or use the model itself to estimate remaining life expectancy for a given age and initial health state.

To aid in intuition, Table 7 provides remaining life expectancy values under exogenous and endogenous approaches for our running example. The row structure of this table mimics the structure needed for \(\tilde{\boldsymbol{\eta}}^{\top}\)—though note that the table only provides values for a subset of ages, not all age classes.

The column based on exogenous life tables (Exogenous-Ref. Life Table) is simply the reference life table life expectancy value as published by the GBD (Global Burden of Disease Collaborative Network 2021). The column marked Endogenous-Model is based on solving for remaining life expectancy using the occupancy based rewards approach discussed above.10 Finally, the last column (Endogenous-Life Table) uses country-specific life expectancy information (by age) published by the GBD (Global Burden of Disease Collaborative Network 2020b). In our running example—which has been structured and (roughly) calibrated to match life table data—the values for the Healthy state are very similar under both endogenous approaches—though in Endogenous-Model, life expectancy values for those who start in the CVD health state are strictly lower, owing to the higher mortality rate from disease.

10 This column essentially reproduces the approach to remaining life expectancy as originally conceived in Caswell and van Daalen (2021). The only difference is that we use the full rewards-based approach (which allows for partial transitions and half-cycle corrections) rather than solving for the fundamental matrix \(\tilde{\mathbf{N}}\) and applying the formula \(\tilde{\boldsymbol{\eta}}_{1}^{\top}=\mathbf{1}_{\tau \omega}^{\top} \tilde{\mathbf{N}}\)

Healthy Longevity Outcome Functions
healthy_longevity_occupancy <- function(params, H, V) {
    with(params,{
        map2(mUtilde,mPtilde,~({
            U = .x
            P = .y
            N = solve(diag(tau*omega)-U)
            h = vec(H) %>% as.matrix()
            not_h = 1-h
            v <- vec(V) %>% as.matrix()
            B1 <- h %*% t(v) + 0.5 * (not_h %*% t(v)) + 0.5 * (v %*% t(not_h)) # Eq. 46
            C1 = 0.5 * (rep(1,alpha) %*%  t(v)) # Eq. 48
            R1 = rbind(cbind(B1, matrix(0, tau * omega, alpha)) ,
                              cbind(C1, diag(alpha))) 
            R2 = R1 * R1
            R3 = R1 * R1 * R1
            Z = cbind(diag(tau*omega),matrix(0,nrow=tau*omega, ncol=alpha))
            e = rep(1,s)
            rho1_ <- t(N)%*% Z %*% t(P * R1) %*% e
            # The following needs to be debugged
            # rho2_ <-
            #   N %*% (Z %*% t(.y * R1) %*% e + 2 * t(.x * B1) %*% rho1_)
            # B2 <- R2[1:(tau * omega), 1:(tau * omega)]
            # rho3_ <- t(N) %*% (Z %*% ((t(.y * R3) %*% e)) + 3 * (t(.x * B2) %*% rho1_) + 3 * (t(.x * B1) %*% rho2_))
            rho1_
        }))
    })
}

healthy_longevity_yll <- function(params, life_expectancy, disc) {
    with(params,{
        map2(mUtilde,mPtilde,~({
            U = .x
            P = .y
            N = solve(diag(tau*omega)-U)
            Z = cbind(diag(tau*omega),matrix(0,nrow=tau*omega, ncol=alpha))
            disc_ = rev(sort(rep(disc,length(tr_names))))
            eta1_ex_ = rev(sort(rep(life_expectancy,length(tr_names))))
            eta1_ex =  eta1_ex_
            
            B1 = matrix(0,nrow=tau*omega, ncol = tau*omega)
            C1 = rbind(matrix(0,nrow=1,ncol=tau*omega),eta1_ex*disc_) 
            R1 = cbind(rbind(B1,C1),matrix(0,nrow=tau*omega+2,ncol=2))
            R2 = R1 * R1
            R3 = R1 * R1 * R1
            Z = cbind(diag(tau*omega),matrix(0,nrow=tau*omega, ncol=alpha))
            e = rep(1,s)
            rho1_ = t(N) %*% Z %*% t(.y * R1) %*% e
            # The following needs to be debugged
            # rho2_ <-
            #   N %*% (Z %*% t(.y * R1) %*% e + 2 * t(.x * B1) %*% rho1_)
            # B2 <- R2[1:(tau * omega), 1:(tau * omega)]
            # rho3_ <- t(N) %*% (Z %*% ((t(.y * R3) %*% e)) + 3 * (t(.x * B2) %*% rho1_) + 3 * (t(.x * B1) %*% rho2_))
            rho1_
        }))
    })
}
Exogenous vs Endogenous Life Expectancy by Age
# Exogenous
exGBD <- 
  params$ExR %>% 
  select(age = Age, exo_gbd = Life.Expectancy)

# Endogenous-Model

H = with(params3,matrix(1,nrow=tau, ncol=omega))
V_LE = with(params3,matrix(1,nrow=tau, ncol = omega))
LE3_ <- params3 %>% healthy_longevity_occupancy(H = H, V = V_LE)

eHealthy <- LE3_ %>% map(~({
  as.data.frame(kronecker(diag(params3$omega),t(c(1,0))) %*% as.matrix(.x)) %>% 
  mutate(age = params3$ages)  %>% 
  mutate(initial = params3$tr_names[1])
})) %>% 
  set_names(params3$tx_names) %>% 
  bind_rows(.id = "strategy") %>% 
  filter(strategy == "natural_history") %>% 
  filter(age %in% params$ExR$Age) %>% 
  select(age,end_model=V1) %>% 
  mutate(state = "Healthy")

eCVD <- LE3_ %>% map(~({
  as.data.frame(kronecker(diag(params3$omega),t(c(0,1))) %*% as.matrix(.x)) %>% 
  mutate(age = params3$ages)  %>% 
  mutate(initial = params3$tr_names[1])
})) %>% 
  set_names(params3$tx_names) %>% 
  bind_rows(.id = "strategy") %>% 
  filter(strategy == "natural_history") %>% 
  filter(age %in% params$ExR$Age) %>% 
  select(age,end_model=V1) %>% 
  mutate(state = "CVD")

# Endogenous - Life Table

eLT <- lt %>% filter(age %in% params$ExR$Age) %>% 
  select(age,end_lt = ex)  %>% 
  as_tibble()

exGBD %>% mutate(state = "Healthy") %>% 
  bind_rows(exGBD %>% mutate(state = "CVD")) %>% 
  left_join(
    eHealthy %>% bind_rows(eCVD), c("age","state")
  ) %>% 
  left_join(
    eLT %>% mutate(state = "Healthy") %>% 
      bind_rows(eLT %>% mutate(state = "CVD")), c("age","state")
  ) %>% 
  arrange(age,rev(state)) %>% 
  filter(age %in% c(5,25,50,95)) %>% 
  select(age,state,exo_gbd,end_model,end_lt) %>% 
  kable(digits = 2, col.names = c("Age","Initial Health State","Exogenous-Ref. Life Table", "Endogenous-Model","Endogenous-Life Table")) %>% 
  kable_styling()
Table 7: Exogenous vs Endogenous Life Expectancy by Age and Initial Health State
Age Initial Health State Exogenous-Ref. Life Table Endogenous-Model Endogenous-Life Table
5 Healthy 84.03 76.40 76.40
5 CVD 84.03 74.20 76.40
25 Healthy 64.15 56.69 56.65
25 CVD 64.15 54.48 56.65
50 Healthy 39.63 32.88 32.75
50 CVD 39.63 30.73 32.75
95 Healthy 5.92 4.10 3.10
95 CVD 5.92 2.76 3.10

We next construct the reward matrices

\[ \begin{aligned} \tilde{\mathbf{B}}_{1} & =\left(\mathbf{0}_{\tau \omega \times \tau \omega}\right) \\ \tilde{\mathbf{C}}_{1} & =\left(\begin{array}{c} \tilde{\boldsymbol{\eta}}_{1}^{\top} \\ \mathbf{0}_{1 \times \tau \omega} \end{array}\right) . \end{aligned} \]

and

\[ \tilde{\mathbf{R}}_{1}=\left(\begin{array}{c|c} \mathbf{0}_{\tau \omega \times \tau \omega} & \mathbf{0}_{\tau \omega \times 2} \\ \hline \tilde{\boldsymbol{\eta}}_{1}^{\top} & \mathbf{0}_{1 \times 2} \\ \mathbf{0}_{1 \times \tau \omega} & \mathbf{0}_{1 \times 2} \end{array}\right) \]

Echoing the approach to occupancy-based rewards above, expected outcomes are based on

\[ \begin{aligned} & \tilde{\boldsymbol{\rho}}_{1}=\tilde{\mathbf{N}}^{\top} \mathbf{Z}\left(\tilde{\mathbf{P}} \circ \tilde{\mathbf{R}}_{1}\right)^{\top} \mathbf{1}_{s} \end{aligned} \] where \(\circ\) denotes element-wise multiplication, \(\tilde{\mathbf{N}}\) is the fundamental matrix

\[ \tilde{\mathbf{N}}=(\mathbf{I}-\tilde{\mathbf{U}})^{-1} \] and \(\mathbf{Z}\) is

\[ \mathbf{Z}=\left(\mathbf{I}_{\tau \omega} \mid \mathbf{0}_{\tau \omega \times \alpha}\right) \]

Total Expected Outcomes

For both occupancy- and transition-based outcomes, total (across all ages) outcomes for each starting health state are calculated as

\[ \boldsymbol{\rho}_{m}^{\text {stage }}(\operatorname{age} x)=\left(\mathbf{e}_{x}^{\top} \otimes \mathbf{I}_{\tau}\right) \tilde{\boldsymbol{\rho}}_{m} \quad \tau \times 1 \] where \(\otimes\) is the Kronecker operator.

Alternatively, we may wish to calculate outcomes separately under different starting ages, and for a specified starting health state (e.g., healthy). This is given by

\[ \boldsymbol{\rho}_{m}^{\text {age }}(\text { stage } i)=\left(\mathbf{I}_{\omega} \otimes \mathbf{e}_{i}^{\top}\right) \tilde{\boldsymbol{\rho}}_{m} \quad \omega \times 1, \]

A Note on Discounting

Though later GBD iterations removed age and time discounting for the purposes of documenting disease burdens worldwide, the World Health Organization’s Choosing Interventions that are Cost-Effective (WHO-CHOICE) program recommends consideration of time discounting of health outcomes (Murray et al. 2020; Bertram et al. 2021). Discounting is also not covered in the original formulation of the Healthy Longevity approach as outlined in Caswell and van Daalen (2021).

While we have set the annual discount rate to zero for this example, our approach adopts the WHO-CHOICE recommendation and includes the option for time discounting in the provided code. Specifically, we apply the cycle-specific discount factor to the values in the rewards matrix \(\mathbf{V}\) and vector \(\mathbf{v}\) for occupancy-based outcomes. For YLL outcomes, we apply the appropriate discounting factor to the age classes in the remaining life expectancy vector \(\tilde{\boldsymbol{\eta}}^{\top}\).

Results

Table 8 adds results based on the healthy longevity approach for comparison. In this table, we calculate YLLs using the exogenous reference life table from the GBD (Global Burden of Disease Collaborative Network 2021).

Remaining life expectancy is identical across approaches, reflecting the fact that we used a half-cycle correction for Approaches 1 and 2, and the Healthy Longevity approach applies a similar half-cycle correction.11 YLDs, YLLs and DALYs are also similar across the three methods.

11 Had we used a different cycle correction method we would yield slightly different results—but the differences are rarely meaningful for optimal decisions.

Calculate DALY Outcomes
# Life Expectancy 

H = with(params3,matrix(1,nrow=tau, ncol=omega))
V_LE = with(params3,matrix(1,nrow=tau, ncol = omega))
# Only include the below if discounting remaining life expectancy
# V_LE[1,] <- disc
# V_LE[2,] <- disc
# V_LE[3,] <- disc

V_YLD = with(params3,matrix(0,nrow=tau, ncol = omega))
V_YLD[2,] <- disc[-length(disc)]*with(params3,dw * Delta_t * (1/r_Delta_t) * (1 - exp(-r_Delta_t)))

V_QALY = with(params3,matrix(0,nrow=tau, ncol = omega))
V_QALY[1,] <- disc[-length(disc)]*with(params3,uH)
V_QALY[2,] <- disc[-length(disc)]*with(params3,uCVD)

LE3_ <- params3 %>% healthy_longevity_occupancy(H = H, V = V_LE)
QALY3_ <- params3 %>% healthy_longevity_occupancy(H = H, V = V_QALY)
YLD3_ <- params3 %>% healthy_longevity_occupancy(H = H, V = V_YLD)

remaining_life_expectancy <- with(params3,(1/r_ann) * (1 - exp(-r_ann * fExR(ages))))
YLL3_ <- params3 %>% healthy_longevity_yll(life_expectancy = remaining_life_expectancy, disc = disc[-length(disc)])
DALY3_ <- map2(YLL3_,YLD3_,~(.x+.y))

LE3 <- LE3_ %>% map(~({
  tmp <- (kronecker(t(c(1,rep(0,params3$omega-1))) ,diag(params3$tau)) %*% as.matrix(.x))
  tmp[1,1]
}))

QALY3 <- QALY3_ %>% map(~({
  tmp <- (kronecker(t(c(1,rep(0,params3$omega-1))) ,diag(params3$tau)) %*% as.matrix(.x))
  tmp[1,1]
}))

YLD3 <- YLD3_ %>% map(~({
  tmp <- (kronecker(t(c(1,rep(0,params3$omega-1))) ,diag(params3$tau)) %*% as.matrix(.x))
  tmp[1,1]
}))

YLL3 <- YLL3_ %>% map(~({
  tmp <- (kronecker(t(c(1,rep(0,params3$omega-1))) ,diag(params3$tau)) %*% as.matrix(.x))
  tmp[1,1]
}))

DALY3 <- DALY3_ %>% map(~({
  tmp <- (kronecker(t(c(1,rep(0,params3$omega-1))) ,diag(params3$tau)) %*% as.matrix(.x))
  tmp[1,1]
}))

result3 <- cbind(LE3, YLD3,YLL3,DALY3) %>%
    as.data.frame() %>%
    mutate_all(~as.numeric(.))  %>%
    rownames_to_column(var="strategy") %>%
    mutate(approach = "Markov Chain With Rewards") %>%
    dplyr::select(approach, strategy, LE = LE3, YLD=YLD3, YLL=YLL3, DALY=DALY3)

tib <- result1 %>%
    bind_rows(result2) %>% 
  bind_rows(result3)

tib %>%
    arrange(strategy) %>%
    select(-strategy) %>%
    kable(digits = 3, col.names = c("Approach","Life Expectancy (Life Table)","Life Expectancy (Model)","YLDs","YLLs","DALYs")) %>% 
    kable_styling() %>% 
    pack_rows(index = c("natural_history" =3, "prevention" = 3, "treatment" = 3,"prevent_treat" = 3)) %>%
    kable_styling()
Table 8: Life Expectancy, YLD, YLL and DALY Outcomes, by Approach
Approach Life Expectancy (Life Table) Life Expectancy (Model) YLDs YLLs DALYs
natural_history
Markov Trace 81.07 81.081 0.363 1.921 2.284
Transition States 81.081 0.363 1.921 2.284
Markov Chain With Rewards 81.081 0.353 2.022 2.376
prevention
Markov Trace 81.188 0.334 1.787 2.121
Transition States 81.188 0.334 1.787 2.121
Markov Chain With Rewards 81.188 0.325 1.882 2.207
treatment
Markov Trace 81.350 0.341 1.585 1.926
Transition States 81.350 0.341 1.585 1.926
Markov Chain With Rewards 81.350 0.331 1.670 2.001
prevent_treat
Markov Trace 81.255 0.370 1.704 2.074
Transition States 81.255 0.370 1.704 2.074
Markov Chain With Rewards 81.255 0.360 1.794 2.155

DALYs for Different Starting Ages

Our models above assumed a starting cohort age of 0. One nice feature of the healthy longevity approach, however, is that we can calculate outcomes for any starting age.12 We can apply the following formula to our constructed transition and reward matrices to yield expected outcomes across ages:

12 We could do this using the Markov-traced approaches, too, but we’d need to re-run the model with a new cohort starting at each age.

\[ \boldsymbol{\rho}_{m}^{\text {age }}(\text { stage } i)=\left(\mathbf{I}_{\omega} \otimes \mathbf{e}_{i}^{\top}\right) \tilde{\boldsymbol{\rho}}_{m} \quad \omega \times 1, \]

Figure 11 plots the results.

Create Plot by Age
p1 = YLL3_ %>% map(~({
  as.data.frame(kronecker(diag(params3$omega),t(c(1,0))) %*% as.matrix(.x)) %>% 
  mutate(age = params3$ages)  %>% 
  mutate(initial = params3$tr_names[1])
})) %>% 
  set_names(params3$tx_names) %>% 
  bind_rows(.id = "strategy") %>% 
  ggplot(aes(x = age, y = V1, colour = strategy, lty=strategy)) + geom_line() + theme_ipsum() + 
  scale_colour_aaas() + 
  geom_dl(method = list("first.points","bumpup", hjust=-1),aes(label = strategy)) +
    theme(legend.position = "none") + ggtitle("YLL") + labs(x = "Age", y = "YLL")

p2 = YLD3_ %>% map(~({
  as.data.frame(kronecker(diag(params3$omega),t(c(1,0))) %*% as.matrix(.x)) %>% 
  mutate(age = params3$ages)  %>% 
  mutate(initial = params3$tr_names[1])
})) %>% 
  set_names(params3$tx_names) %>% 
  bind_rows(.id = "strategy") %>% 
  ggplot(aes(x = age, y = V1, colour = strategy, lty=strategy)) + geom_line() + theme_ipsum() + 
  scale_colour_aaas() + 
  geom_dl(method = list("first.points","bumpup", hjust=-1),aes(label = strategy))  + 
  theme(legend.position = "none") + ggtitle("YLD") + labs(x = "Age", y = "YLD")

p3 = DALY3_ %>% map(~({
  as.data.frame(kronecker(diag(params3$omega),t(c(1,0))) %*% as.matrix(.x)) %>% 
  mutate(age = params3$ages)  %>% 
  mutate(initial = params3$tr_names[1])
})) %>% 
  set_names(params3$tx_names) %>% 
  bind_rows(.id = "strategy") %>% 
  ggplot(aes(x = age, y = V1, colour = strategy, lty=strategy)) + geom_line() + theme_ipsum() + 
  scale_colour_aaas() + 
  geom_dl(method = list("first.points","bumpup", hjust=-1),aes(label = strategy))  + 
  theme(legend.position = "none") + ggtitle("DALY") + labs(x = "Age", y = "DALY")


p3 + p1  / p2
Figure 11: DALYs by Model Starting Age
Important

Note that had we employed an annual discount rate in our results, the age-based plots shown in Figure 11 are not recommended, as the various later ages would be discounted and would therefore not represent cohorts with different initial agess from the same baseline period.

DALYs Based on Endogenous Life Expectancy

We next explore several approaches for calculating DALYs based on endogenous life expectancy.

DALY Shortcut: QALY-like DALY

Some applications and modeling platforms apply a “shortcut” to estimate DALYs by defining a payoff vector that “rewards” time in the sick state using the disability weight (as in the approaches above), and also applies a payoff value of 1 for each cycle spent in the disease-related death state.

To implement this shortcut we multiply state occupancy in a given cycle by the payoff vector \(\mathbf{d_{QALYDALY}}\),

\[ \mathbf{d}_{QALYDALY} = \left[ \begin{array}{c} 0.0 \\ \text{dw}_{CVD} \\ 0.0 \\ 1.0 \end{array} \right] \begin{array}{l} \text{Healthy} \\ \text{CVD} \\ \text{DeathOC} \\ \text{DeathCVD} \\ \end{array} \] where \(\text{dw}_{CVD}\) is the disability weight for CVD.

Important

As we will see in the results below, this approach will yield different results for DALYs because it conflates the model time horizon with life expectancy. A primary issue is that it applies a payoff value of 1.0 to an absorbing state; the number of times this payoff value is applied to the population is purely a function of the time horizon in the model. In other words, we can arbitrarily increase or decrease the estimated contribution of YLLs to DALYs by lengthening or shortening the number of cycles in our model. Since occupancy in an absorbing state will remain positive even if everyone in the cohort has died, we will continue to accrue (or lose) YLLs as we add or subtract cycles to the end of the Markov trace

We do not face a similar issue when estimating YLDs because if everyone has entered an absorbing state, we are simply multiplying the disability weight by a (living) health state occupancy value that is essentially zero.

Calculate Endogenous DALYs
# QALY-LIKE DALY
qaly_daly_ = with(params1,(matrix(c(0,
               (dw * Delta_t * (1/r_Delta_t) * (1 - exp(-r_Delta_t))) ,
              0,
              1),
            dimnames = list(c(
                c(tr_names,ab_names)
            ), c("DW")))
))

# QALY-LIKE DALY
YLL_qaly_daly_ = with(params1,(matrix(c(0,
               0 ,
              0,
              1),
            dimnames = list(c(
                c(tr_names,ab_names)
            ), c("DW")))
))

YLL_QALY_DALYt <- trace1 %>% map( ~ ({
    tmp = as.matrix(.x) %*% YLL_qaly_daly_
    tmp
}))

YLL_QALY_DALY = YLL_QALY_DALYt %>% map(~sum(.x*  disc * gen_wcc(params1$omega, method = params1$cycle_correction)))


QALY_DALYt <- trace1 %>% map( ~ ({
    tmp = as.matrix(.x) %*% qaly_daly_
    tmp
}))

QALY_DALY = QALY_DALYt %>% map(~sum(.x*  disc * gen_wcc(params1$omega, method = params1$cycle_correction)))
DALYs based on endogenous life expectancy
# Caswell and van Daalen (2021) recommend using eq (51), which multiplies the 
# fundamental matrix (eq 16) by a vector of ones. However, this estimate
# of longevity does not make any kind of cycle correction. Instead, we will
# use the estimate of life expectancy calculated earlier (LE3) to fill out the 
# "reward" matrix for remaining life expectancy at each age. The 
# code to use the original approach is provided (and commented out) below, however.
# N = with(params3,({
#   mUtilde %>% map(~({
#     solve(diag(tau*omega)-.x)
#   }))
# }))
# 
# remaining_life_expectancy_endogenous = as.vector(t(rep(1,params3$tau*params3$omega)) %*% N[[1]]) %>% {.[seq(1,params3$tau*params3$omega,2)]}
# YLL3_endogenous_ <- params3 %>% healthy_longevity_yll(life_expectancy = remaining_life_expectancy_endogenous, disc = disc[-length(disc)])

remaining_life_expectancy_endogenous <- 
  LE3_ %>% map(~({.x[seq(1,params3$tau*params3$omega,2)]})) %>% {.$natural_history}
YLL3_endogenous_ <- params3 %>% healthy_longevity_yll(life_expectancy = remaining_life_expectancy_endogenous, disc = disc[-length(disc)])

YLL3_endogenous <- YLL3_endogenous_ %>% map(~({
  tmp <- (kronecker(t(c(1,rep(0,params3$omega-1))) ,diag(params3$tau)) %*% as.matrix(.x))
  tmp[1,1] # life expectancy when starting healthy
}))

# Endogeneous life expectancy only affects YLLs, so we can simply use the YLD value from above.
YLD3_endogenous <- YLD3_ %>% map(~({
  tmp <- (kronecker(t(c(1,rep(0,params3$omega-1))) ,diag(params3$tau)) %*% as.matrix(.x))
  tmp[1,1]
}))

DALY3_endogenous_ <- map2(YLL3_endogenous_,YLD3_,~(.x+.y))

DALY3_endogenous <- DALY3_endogenous_ %>% map(~({
  tmp <- (kronecker(t(c(1,rep(0,params3$omega-1))) ,diag(params3$tau)) %*% as.matrix(.x))
  tmp[1,1]
}))


result4 <- cbind(LE3, YLD3_endogenous, YLL3_endogenous, DALY3_endogenous) %>%
    as.data.frame() %>%
    mutate_all(~as.numeric(.))  %>%
    rownames_to_column(var="strategy") %>%
    mutate(approach = "Markov Chain With Rewards - Endogenous") %>%
    dplyr::select(approach, strategy ,LE = LE3, YLD = YLD3_endogenous, YLL = YLL3_endogenous,  DALY=DALY3_endogenous) %>% 
  bind_rows(
     cbind(LE,YLD,YLL_QALY_DALY,QALY_DALY) %>%
      as.data.frame() %>%
      mutate_all(~as.numeric(.))  %>%
      rownames_to_column(var="strategy") %>%
      mutate(approach = "Markov Trace - QALY-like DALY") %>%
      dplyr::select(approach, strategy, LE, YLD , YLL= YLL_QALY_DALY, DALY=QALY_DALY)
  )

tib <- result1 %>%
    bind_rows(result2) %>% 
  bind_rows(result3) %>% 
  bind_rows(result4)

tib %>%
    arrange(strategy) %>%
    select(-strategy) %>%
    kable(digits = 3, col.names = c("Approach","Life Expectancy (Life Table)","Life Expectancy (Model)","YLDs","YLLs","DALYs")) %>% 
    kable_styling() %>% 
    pack_rows(index = c("natural_history" =5, "prevention" = 5, "treatment" = 5,"prevent_treat" = 5)) %>%
    kable_styling()
Approach Life Expectancy (Life Table) Life Expectancy (Model) YLDs YLLs DALYs
natural_history
Markov Trace 81.07 81.081 0.363 1.921 2.284
Transition States 81.081 0.363 1.921 2.284
Markov Chain With Rewards 81.081 0.353 2.022 2.376
Markov Chain With Rewards - Endogenous 81.081 0.353 1.484 1.837
Markov Trace - QALY-like DALY 81.081 0.363 6.409 6.772
prevention
Markov Trace 81.188 0.334 1.787 2.121
Transition States 81.188 0.334 1.787 2.121
Markov Chain With Rewards 81.188 0.325 1.882 2.207
Markov Chain With Rewards - Endogenous 81.188 0.325 1.380 1.705
Markov Trace - QALY-like DALY 81.188 0.334 5.980 6.314
treatment
Markov Trace 81.350 0.341 1.585 1.926
Transition States 81.350 0.341 1.585 1.926
Markov Chain With Rewards 81.350 0.331 1.670 2.001
Markov Chain With Rewards - Endogenous 81.350 0.331 1.223 1.555
Markov Trace - QALY-like DALY 81.350 0.341 5.348 5.689
prevent_treat
Markov Trace 81.255 0.370 1.704 2.074
Transition States 81.255 0.370 1.704 2.074
Markov Chain With Rewards 81.255 0.360 1.794 2.155
Markov Chain With Rewards - Endogenous 81.255 0.360 1.315 1.675
Markov Trace - QALY-like DALY 81.255 0.370 5.732 6.102

Incremental Outcomes

DALY changes
tib %>% 
  select(approach,strategy,YLD,YLL,DALY) %>% 
  left_join(
    tib %>% 
    filter(strategy == "natural_history") %>% 
    select(-strategy) %>% 
    select(approach,YLD_ref = YLD,YLL_ref = YLL,DALY_ref = DALY), c("approach")
  ) %>% 
  mutate(YLD = YLD - YLD_ref,
         YLL = YLL - YLL_ref,
         DALY = DALY - DALY_ref) %>% 
  select(approach,strategy,YLD,YLL,DALY) %>% 
 
  mutate(approach = factor(approach, levels = c("Markov Trace","Transition States","Markov Chain With Rewards","Markov Chain With Rewards - Endogenous","Markov Trace - QALY-like DALY"))) %>% 
  filter(strategy != "natural_history") %>% 
  gather(outcome,value,-approach,-strategy) %>% 
  mutate(outcome = factor(outcome, levels = c("YLD","YLL","DALY"))) %>% 
  mutate(value = value*-1) %>% 
  ggplot(aes(x=strategy, y = value,  fill = approach)) + geom_bar(stat="identity", position = position_dodge()) +
  facet_grid(~outcome, scales="free") +
  theme_ipsum() +
  scale_fill_aaas(name="") + 
  theme(legend.position="top") +
  geom_hline(aes(yintercept = 0)) +
  coord_flip() +
  labs(x = "", y = "Change relative to natural_history\nNote: Scale changes in each panel") 
Figure 12: Disability-Adjusted Life Year Outcome Changes Relative to Natural History Model

What Explains the Difference

trace1$natural_history %>% as_tibble()  %>% 
  mutate(Alive = Healthy + CVD)  %>% 
  select(Alive, DeathOC, DeathCVD)  %>% 
  mutate(cycle = row_number()) %>% 
  select(cycle,everything()) %>% 
  tail(n = 10) %>% 
  kable(digits = 3) %>% 
  kable_styling()
Table 9: “Last Ten Cycles of Markov Trace”
cycle Alive DeathOC DeathCVD
112 0 0.812 0.188
113 0 0.812 0.188
114 0 0.812 0.188
115 0 0.812 0.188
116 0 0.812 0.188
117 0 0.812 0.188
118 0 0.812 0.188
119 0 0.812 0.188
120 0 0.812 0.188
121 0 0.812 0.188

References

Anand, Sudhir, and Sanjay G. Reddy. 2019. “The Construction of the DALY: Implications and Anomalies.” SSRN Electronic Journal. https://doi.org/10.2139/ssrn.3451311.
Bertram, Melanie Y., Jeremy A. Lauer, Karin Stenberg, and Tessa Tan Torres Edejer. 2021. “Methods for the Economic Evaluation of Health Care Interventions for Priority Setting in the Health System: An Update From WHO CHOICE.” International Journal of Health Policy and Management, January. https://doi.org/10.34172/ijhpm.2020.244.
Caswell, Hal, and Silke van Daalen. 2021. “Healthy Longevity from Incidence-Based Models: More Kinds of Health Than Stars in the Sky.” Demographic Research 45 (July): 397–452. https://doi.org/10.4054/demres.2021.45.13.
Caswell, Hal, and Virginia Zarulli. 2018. “Matrix Methods in Health Demography: A New Approach to the Stochastic Analysis of Healthy Longevity and DALYs.” Population Health Metrics 16 (1). https://doi.org/10.1186/s12963-018-0165-5.
Global Burden of Disease Collaborative Network. 2020a. “Global Burden of Disease Study 2019 (GBD 2019) Disability Weights.” Institute for Health Metrics; Evaluation (IHME). https://doi.org/10.6069/1W19-VX76.
———. 2020b. “Global Burden of Disease Study 2019 (GBD 2019) Life Tables 1950-2019.” Institute for Health Metrics; Evaluation (IHME). https://doi.org/10.6069/1PF5-1M37.
———. 2020c. “Global Burden of Disease Study 2019 (GBD 2019) Results.” Seattle, United States: Institute for Health Metrics and Evaluation (IHME).
———. 2021. “Global Burden of Disease Study 2019 (GBD 2019) Reference Life Table.” Institute for Health Metrics; Evaluation (IHME). https://doi.org/10.6069/1D4Y-YQ37.
Henderson, Harold V., and S. R. Searle. 1981. “The Vec-Permutation Matrix, the Vec Operator and Kronecker Products: A Review.” Linear and Multilinear Algebra 9 (4): 271–88. https://doi.org/10.1080/03081088108817379.
Murray, Christopher J L, Aleksandr Y Aravkin, Peng Zheng, Cristiana Abbafati, Kaja M Abbas, Mohsen Abbasi-Kangevari, Foad Abd-Allah, et al. 2020. “Global Burden of 87 Risk Factors in 204 Countries and Territories, 19902019: A Systematic Analysis for the Global Burden of Disease Study 2019.” The Lancet 396 (10258): 1223–49. https://doi.org/10.1016/s0140-6736(20)30752-2.