do.call(knitr::read_chunk, list(path = "../inst/vignettes-R/01-markov-cohort.R"))
The most commonly used model for cost-effectiveness analysis (CEA) is the cohort discrete time state transition model (cDTSTM), commonly referred to as a Markov cohort model. In this tutorial we demonstrate implementation with R
of the simplest of cDSTMs, a time-homogeneous model with transition probabilities that are constant over time. The entire analysis can be run using Base R (i.e., without installing any packages). However, we will use the following packages to create a nice looking cost-effectiveness table.
As an example, we will consider the 4-state sick-sicker model that has been described in more detail by Alarid-Escudero et al. The model will be used to compare two treatment strategies, a "New" treatment and the existing "standard of care (SOC)". The model consists 4 health states. Ordered from worst to best to worst, they are: Healthy (H), Sick (S1), Sicker (S2), and Death (D). Possible transitions from each state are displayed in the figure below.
knitr::include_graphics("sick-sicker.png")
Transition probabilities are the building blocks of Markov cohort models and used to simulate the probability that a cohort of patients is in each health state at each model cycle. To set notation, let $p_t$ be the transition probability matrix governing transitions from one time period (i.e., model cycle) to the next. $x_t$ is the state occupancy vector at time $t$. In this example, $p_t$ is a $4 \times 4$ matrix and $x_t$ is a $1 \times 4$ vector containing the proportion of patients in each of the 4 health states.
At time $0$, the state vector is $x_0 = (1, 0, 0, 0)$ since all patients are healthy. The state vector at time $t+1$ for each of $T$ model cycles can be computed using matrix multiplication,
$$ x_{t+1}= x_t p_t, \quad t = 0,\ldots,T $$ The matrix containing state vectors across all model cycles is often referred to as the "Markov trace" in health economics. Note that since we are considering a time-homogeneous model in this example, we can remove the subscript from the transition matrix and set $p_t = p$.
To perform a CEA, Markov models estimate expected (i.e., average) costs and outcomes for the cohort of interest. In our examples, quality-adjusted life-years (QALYs) will be used as the outcome.
Costs and QALYs are computed by assigning values to the health states (i.e., "state values") and weighting the time spent in each state by these state values. For example, if utility in each of the four health states is given by the $4 \times 1$ vector $u = (1, 0.75, 0.5, 0)^T$ and say, $x_1 = (.8, .1, 0.08, 0.02)$, then the weighted average utility would be given by $x_{1}u = 0.915$. More generally, we can define a state vector at time $t$ as $z_t$ so that the expected value at time $t$ is given by
$$ EV_t = x_{t}z_{t} $$
Future cost and outcomes are discounted using a discount rate. In discrete time, the "discount weight" at time $t$ is given by $1/(1 + r)^t$ where $r$ is the discount rate; in continuous time, it is given by $e^{-rt}$. We will use discrete time here, meaning that the present value of expected values are given by,
$$ PV_t = \frac{EV_t}{(1+r)^t} $$ The simplest way to aggregate discounted costs across model cycles is with the net present value,
$$ NPV = \sum_{t} PV_t $$
It is important to note that in mathematical terms this a discrete approximation to a continuous integral, also known as a Riemann sum. That is, we only know that an expected value lies within a time interval (e.g., in model cycle 1, between year 0 and 1; in model cycle 2, between year 1 and 2; and so on). If we approximate the integral using values at the start of the interval (i.e., transitions occur at the end of the interval), then it is known as a left Riemann sum; conversely, if we use values at the end of the interval (i.e., transitions happen immediately), then it is known as a right Riemann sum. Life-years are overestimated when using a left Riemann sum and underestimated when using a right Riemann sum. A preferable option is to use an average of values at the left and right endpoints (i.e., the trapezoid rule). That said, we will assume events occur at the start of model cycles for simplicity.
The annual transition probabilities for SOC among our cohort of interest, say 25-year old patients, are defined as follows.
These can be used to derive the probabilities of remaining in the same state during a model cycle.
Using these probabilities, the transition probability matrix can then be defined.
In evidence synthesis and cost-effectiveness modeling, treatment effects are typically estimated in relative terms; i.e., the effect of an intervention is assessed relative to a reference treatment. In this case, the SOC is the reference treatment and the effectiveness of the new treatment is assessed relative to the SOC. For simplicity, we will assume that treatment effects are defined in terms of the relative risk, which is assumed to reduce the probability of all transitions to a more severe health state by an equal amount. Note that this is somewhat unrealistic since relative risks are a function of baseline risk and would be unlikely to be equal for each transition. A more appropriate model would define treatment effects in terms of a measure that is invariant to baseline risk such as an odds ratio (which might still vary for each transition).
The relative risk can then be used to create the transition matrix for the new treatment. We will use assume the relative risk is $0.8$.
Utility and (annualized) costs are defined below. We consider two types of costs: medical and treatment. Both utility and costs are 0 in the death state. Treatment costs are assumed equal in each health state.
To simulate health state probabilities, we must specify a state vector at time 0. Each patient will start in the Healthy state.
The state vector during cycle $1$ for SOC is computed using simple matrix multiplication.
x_init %*% p_soc
We can also easily compute the state vector at cycle 2 for SOC.
x_init %*% p_soc %*% p_soc
A for loop can be used to compute the state vector at each model cycle. We created a function in the rcea
package to do this so that we can reuse it. The model will be simulated until a maximum age of 110; that is, for 85 years for a cohort of 25-year olds.
rcea::sim_markov_chain
We perform the computation for both the SOC and new treatment. As expected, patients remain in less severe health states longer when using the new treatment.
To compute discounted costs and QALYS, it is helpful to write a general function for computing a present value.
rcea::pv
To illustrate a computation, lets start with discounted expected QALYs after the first model cycle.
x_soc[2, ] # State occupancy probabilities after 1st cycle invisible(sum(x_soc[2, 1:3])) # Expected life-years after 1st cycle invisible(sum(x_soc[2, ] * utility)) # Expected utility after 1st cycle sum(pv(x_soc[2, ] * utility, .03, 1)) # Expected discounted utility after 1st cycle
Now let's compute expected (discounted) QALYs for each cycle.
We can do the same for costs. The first column is medical costs and the second column is treatment costs.
We conclude by computing the incremental cost-effectiveness ratio (ICER) with the new treatment relative to SOC. It can be computed by summing the costs and QALYs we simulated in the previous section across all model cycles. Note that since we are assuming that transitions happen immediately, we exclude costs and QALYs measured at the start of the first model cycle.
For the sake of presentation, we might want to do a some extra work and create a nice looking table.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.