#| purl = FALSE, #| include = FALSE # read vignette source chunks from corresponding testthat script knitr::read_chunk( file.path("..", "tests", "testthat", "test-model-Sumatriptan.R") ) # read vignette build utility functions knitr::read_chunk(file.path("vutils.R"))
#| gbp, #| echo = FALSE
#| include = FALSE, #| purl = FALSE knitr::opts_chunk$set( echo = FALSE, collapse = TRUE, comment = "#>" )
#| purl = FALSE #nolint start
library(rdecision)
#| purl = FALSE #nolint end
This vignette is an example of modelling a decision tree using the rdecision
package. It is based on the example given by Briggs [-@briggs2006] (Box 2.3)
which itself is based on a decision tree which compared oral Sumatriptan versus
oral caffeine/Ergotamine for migraine [@evans1997]. In this vignette, we
consider the problem from the perspective of a provincial health department.
The following code defines the variables for cost, utility and effect that will be used in the model. There are 14 variables in total; 4 costs, 4 utilities and 6 probabilities.
#| modvars, #| echo = TRUE
The following code constructs the decision tree. In the
formulation used by rdecision
, a decision tree is a form of
arborescence, a directed graph of nodes and edges, with a single
root and a unique path from the root to each leaf node. Decision trees
comprise three types of node: decision, chance and leaf nodes and two
types of edge: actions (whose sources are decision nodes) and reactions
(whose sources are chance nodes), see Figure 1.
#| model, #| echo = TRUE
#| results = "hide", #| fig.keep = "all", #| fig.align = "center", #| fig.cap = "Figure 1. Decision tree for the Sumatriptan model" DT$draw(border = TRUE)
The method evaluate
of decision tree objects computes
the probability, cost and utility of each strategy for the model. A strategy
is a unanimous prescription of the actions at each decision node. In this
example there is a single decision node with two actions, and the strategies
are simply the two forms of treatment to be compared. More complex decision
trees are also possible.
The paths traversed in each strategy can be evaluated individually
using the method evaluate(by = "path")
. In rdecision
a strategy is defined
as a set of action edges with one action edge per decision node. It is necessary
to use the option by = "path"
only if information about each pathway is
required; normally it is sufficient to call evaluate
which will automatically
aggregate the evaluation by strategy.
The evaluation of each pathway, for each strategy, is done as follows:
#| eval-by-path, #| echo = TRUE
and yields the following table:
#| echo = FALSE knitr::kable( ep[, c("Leaf", "Probability", "Cost", "Utility")], align = "lrrr", digits = c(2L, 4L, 2L, 5L), format.args = list(scientific = FALSE) )
There are, as expected, ten pathways (5 per strategy). The expected
cost, utility and QALY (utility multiplied by the time horizon of the model) for
each choice can be calculated from the table
above, or by invoking the evaluate
method of a decision tree object with the
default parameter by = "strategy"
.
#| eval-by-strategy, #| echo = TRUE
This gives the following result, consistent with that reported by Evans et al [-@evans1997].
#| echo = FALSE knitr::kable( es[, c("d1", "Cost", "Utility", "QALY")], align = "lrrr", digits = c(2L, 2L, 4L, 4L), format.args = list(scientific = FALSE) )
#| icer-basecase, #| echo = FALSE
The incremental cost was $Can r gbp(x = delta_c, p = TRUE)
(r gbp(x = cost_s, p = TRUE)
- r gbp(x = cost_c, p = TRUE)
)
and the incremental utility was r round(delta_u, 2L)
(r round(utility_s, 2L)
- r round(utility_c, 2L)
). Because the time
horizon of the model was 1 day, the incremental QALYs was the incremental
annual utility divided by 365, and the ICER was therefore equal to r gbp(icer)
\$Can/QALY, within 5% of the published estimate (29,366 \$Can/QALY).
Evans et al [-@evans1997] reported the ICER for various alternative values of input variables. For example (their Table VIII), they reported that the ICER was 60,839 $Can/QALY for a relative increase in effectiveness of 9.1% (i.e., when the relief from Sumatriptan was 9.1 percentage points greater than that of Caffeine-Ergotamine) and 18,950 $Can/QALY for a relative increase in effectiveness of 26.8% (these being the lower and upper confidence intervals of the estimate of effectiveness from meta-analysis).
To calculate these ICERs, we set the value of the model variable
p_sumatriptan_relief
, and re-evaluate the model. The lower range of ICER
(with the greater relative increase in effectiveness) is calculated as follows:
#| relief-threshold-upper, #| echo = TRUE
#| icer-upper, #| echo = FALSE
This yields the following table, from which the ICER is calculated as
r gbp(icer_upper)
\$Can/QALY, close to the published estimate of
18,950 \$Can/QALY.
#| echo = FALSE knitr::kable( es[, c("d1", "Cost", "Utility", "QALY")], align = "lrrr", digits = c(2L, 2L, 4L, 4L), format.args = list(scientific = FALSE) )
The upper range of ICER (with the smaller relative increase in effectiveness) is calculated as follows:
#| relief-threshold-lower, #| echo = TRUE
#| icer-lower, #| echo = FALSE
This yields the following table, from which the ICER is calculated as
r gbp(icer_lower)
\$Can/QALY, close to the published estimate of
60,839 \$Can/QALY.
#| echo = FALSE knitr::kable( es[, c("d1", "Cost", "Utility", "QALY")], align = "lrrr", digits = c(2L, 2L, 4L, 4L), format.args = list(scientific = FALSE) )
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.