knitr::opts_chunk$set(echo = TRUE)
library(youthu) library(ggplot2) library(ready4use) set.seed(1234)
This vignette illustrates the rationale for and practical decision-making utility of youthu's QALYs prediction workflow. Note, this example is illustrated with fake data and should not be used to inform decision-making.
The main motivation behind the youthu package is to extend the types of economic analysis that can be undertaken with both single group (e.g. pilot study, health service records) and matched groups (e.g. trial) longitudinal datasets that do not include measures of health utility. This article focuses on its application to matched group datasets.
First, we must first import our data. In this example we will use a fake dataset.
ds_tb <- make_fake_ds_two()
Our dataset includes r ds_tb$match_idx_int %>% unique() %>% length()
matched comparisons, with each comparison containing baseline and follow-up records for one intervention arm participant and one control arm participant. The first few records are as follows.
ds_tb %>% head() %>% ready4show::print_table(output_type_1L_chr = "HTML", caption_1L_chr = "First few records from input dataset", scroll_box_args_ls = list(width = "100%"))
This dataset contains features that make it possible to use in conjunction with youthu's economic analysis functions. These requirements are described in the vignette about finding and using models compatible models to predict QALYs;
The dataset also contains a cost variable, which is a requirement for most, though not all, of the economic analyses that can be undertaken with youthu.
A notable omission from the dataset is any measure of utility. This omission means that, in the absence of using mapping algorithms such as those included with youthu, the most feasible types of economic evaluation to apply to this dataset would likely be cost-consequence analysis (where a synopsis of the differences in a range of measures are presented alongside cost differences) and cost-effectiveness analysis (where a summary statistic - the incremental cost-effectiveness ratio or ICER - is calculated by dividing differences in costs by differences in a single outcome measure).
These types of economic analyses can be relatively simple to interpret if either the intervention or control arm is simultaneously cheaper and more effective across all included outcome measures. However, these conditions don't hold in our sample data.
summary((ds_tb %>% dplyr::filter(study_arm_chr == "Control" & round == "Baseline"))[5:6])
summary((ds_tb %>% dplyr::filter(study_arm_chr == "Control" & round == "Follow-up"))[5:7])
summary((ds_tb %>% dplyr::filter(study_arm_chr == "Intervention" & round == "Baseline"))[5:6])
summary((ds_tb %>% dplyr::filter(study_arm_chr == "Intervention" & round == "Follow-up"))[5:7])
The pattern of results summarised above create some significant barriers to meaningfully interpreting economic evaluations that are based on cost-consequence or cost-effectiveness analysis:
A cost-effectiveness analysis in which change in PHQ-9 was the benefit measure would be difficult to interpret as the Intervention arm is both more effective and more costly, which begs the question is it worth paying the extra dollars for this improvement? Also - would a judgment of cost-effectiveness remain the same if the study had measured a slightly different incremental benefit or recorded change over a longer or shorter time horizon? It is likely that there is no commonly used value for money benchmark for improvements measured in PHQ-9, nor is there any time weighting associated with the measure. Furthermore, if the potential funding for the intervention is from a budget that is allocated to non-depressive illnesses (e.g. physical health), results from a cost-effectiveness analysis using PHQ-9 as its benefit measure are not readily comparable with economic evaluations of interventions from other illness groups using different benefit measures that are potentially competing for the same scarce funding.
A cost consequence analyses that summarised the differences in costs with the differences in changes in PHQ-9 and SOFAS score would be difficult to interpret because while the intervention is more effective than control for improvements measured on PHQ-9 (where lower scores are better), the control group is superior if benefits are based on functioning improvements as measured by SOFAS scores (where higher scores are better). The lack of any formal weighting for how to trade off clinical symptoms and functioning means that interpretation of this analysis will be highly subjective and likely to change across potential decision makers.
These types of short-comings can be significantly addressed by undertaking cost-utility analyses (CUAs) as:
The rest of this article demonstrates how youthu functions can be used to undertake CUA based analyses on the type of data we have just profiled.
Our first step is to identify which youthu models we will use to predict adolescent AQoL-6D and apply these models to our data. This step was explained in more detail in another vignette article about finding and using transfer to utility models, so will be dealt with briefly here.
We now make sure that our dataset can be used as a prediction dataset in conjunction with the model we intend using.
predn_ds_ls <- make_predn_metadata_ls(ds_tb, cmprsn_groups_chr = c("Intervention", "Control"), cmprsn_var_nm_1L_chr = "study_arm_chr", costs_var_nm_1L_chr = "costs_dbl", id_var_nm_1L_chr = "fkClientID", msrmnt_date_var_nm_1L_chr = "date_psx", round_var_nm_1L_chr = "round", round_bl_val_1L_chr = "Baseline", utl_var_nm_1L_chr = "AQoL6D_HU", mdls_lup = get_mdls_lup(utility_type_chr = "AQoL-6D", mdl_predrs_in_ds_chr = c("PHQ9 total score", "SOFAS total score"), ttu_dv_nms_chr = "TTU"), mdl_nm_1L_chr = "PHQ9_SOFAS_1_OLS_CLL")
We now use our preferred model to predict health utility from the measures in our dataset.
ds_tb <- add_utl_predn(ds_tb, predn_ds_ls = predn_ds_ls) %>% dplyr::select(fkClientID, round, study_arm_chr, date_psx, duration_prd, dplyr::everything())
Next we combine the health utility data with the interval between measurement data to calculate QALYs and add them to the dataset.
ds_tb <- ds_tb %>% add_qalys_to_ds(predn_ds_ls = predn_ds_ls, include_predrs_1L_lgl = T, reshape_1L_lgl = T)
ds_tb %>% head() %>% ready4show::print_table(output_type_1L_chr = "HTML", caption_1L_chr = "First few records from updated dataset with QALYs", use_lbls_as_col_nms_1L_lgl = T, scroll_box_args_ls = list(width = "100%"))
Now we can run the main economic analysis. This is implemented by the make_hlth_ec_smry
{.R} function, which first bootstraps the dataset (implemented by the boot
function from the boot
package) before passing the mean values for costs and QALYs from each bootstrap sample to with bcea
function of the BCEA
package to calculate a range of health economic statistics. For this example we pass a value of 50,000 for the willingness to pay parameter, as this is the dollar amount commonly used in Australia as a benchmark for the value of a QALY.
Note, for this illustrative example we only request 1000 bootstrap iterations - in practice this number may be higher.
he_smry_ls <- ds_tb %>% make_hlth_ec_smry(predn_ds_ls = predn_ds_ls, wtp_dbl = 50000, bootstrap_iters_1L_int = 1000L)
As part of the output of the make_hlth_ec_smry
{.R} function is a BCEA object, we can use the BCEA package to produce a number of graphical summaries of economic results. One of the most important is the production of a cost-effectiveness plane. This plot highlights that, with an ICER of \$r he_smry_ls$ce_res_ls$ICER %>% format(big.mark =",")
, r ifelse(he_smry_ls$ce_res_ls$ceac[he_smry_ls$ce_res_ls$k==50000]==0.5,"half",ifelse(he_smry_ls$ce_res_ls$ceac[he_smry_ls$ce_res_ls$k==50000]<0.5,"less than half","most"))
of the bootstrapped iteration incremental cost and QALY pairs fall within the zone of cost-effectiveness (green). In fact, at the cost-effectiveness threshold we supplied, the results suggest there is a r he_smry_ls$ce_res_ls$ceac[he_smry_ls$ce_res_ls$k==50000] * 100
% probability that the intervention is cost-effective.
BCEA::ceplane.plot(he_smry_ls$ce_res_ls, wtp =50000, graph = "ggplot2", theme = ggplot2::theme_light())
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.