This is a replication file for the manuscript. It can be used to produce an HTML file that displays the results without the text with:
# rmarkdown::render("replication.R", output_format = "html_document")
Replication was performed by the authors on macOS Mojave 10.14.6. See the Session Information below for further details.
Package versioning is managed using the renv
package. Packages can be installed by cloning the GitHub repository available at https://github.com/hesim-dev/hesim-manuscript and running renv::restore()
.
library("data.table")
library("flexsurv")
library("ggplot2")
library("hesim")
library("knitr")
library("magrittr")
library("msm")
opts_chunk$set(
tidy = FALSE, eval = TRUE, cache = TRUE,
fig.height = 4, fig.width = 6
)
options(prompt = "> ", continue = "+ ", width = 120, useFancyQuotes = TRUE)
ggplot2::theme_set(ggplot2::theme_bw())
set.seed(102)
# Define transitions
tmat <- rbind(
c(NA, 1, 2),
c(NA, NA, 3),
c(NA, NA, NA)
)
colnames(tmat) <- rownames(tmat) <- c("Stable", "Progression", "Dead")
print(tmat)
## Stable Progression Dead
## Stable NA 1 2
## Progression NA NA 3
## Dead NA NA NA
# hesim data
n_patients <- 1000
patients <- data.table(
patient_id = 1:n_patients,
age = rnorm(n_patients, mean = 45, sd = 7),
female = rbinom(n_patients, size = 1, prob = .51)
)
states <- data.table(
state_id = c(1, 2),
state_name = c("Stable", "Progression") # Non-death health states
)
strategies <- data.table(
strategy_id = 1:3,
strategy_name = c("SOC", "New 1", "New 2"),
soc = c(1, 0, 0),
new1 = c(0, 1, 0),
new2 = c(0, 0, 1)
)
hesim_dat <- hesim_data(
strategies = strategies,
patients = patients,
states = states
)
print(hesim_dat)
## $strategies
## strategy_id strategy_name soc new1 new2
## 1: 1 SOC 1 0 0
## 2: 2 New 1 0 1 0
## 3: 3 New 2 0 0 1
##
## $patients
## patient_id age female
## 1: 1 46.26366 1
## 2: 2 50.49314 1
## 3: 3 35.52785 1
## 4: 4 58.88309 0
## 5: 5 53.66930 0
## ---
## 996: 996 54.60555 0
## 997: 997 50.10654 0
## 998: 998 45.02035 0
## 999: 999 45.60573 1
## 1000: 1000 39.45426 0
##
## $states
## state_id state_name
## 1: 1 Stable
## 2: 2 Progression
##
## attr(,"class")
## [1] "hesim_data"
labs_indiv <- get_labels(hesim_dat)
print(labs_indiv)
## $strategy_id
## SOC New 1 New 2
## 1 2 3
##
## $state_id
## Stable Progression Death
## 1 2 3
# Estimation data
onc3[patient_id %in% c(1, 2)] %>%
kable()
from | to | strategy_name | female | age | patient_id | time_start | time_stop | status | transition_id | strategy_id | time |
---|---|---|---|---|---|---|---|---|---|---|---|
Stable | Progression | New 2 | 0 | 59.85813 | 1 | 0.000000 | 2.420226 | 1 | 1 | 3 | 2.420226 |
Stable | Death | New 2 | 0 | 59.85813 | 1 | 0.000000 | 2.420226 | 0 | 2 | 3 | 2.420226 |
Progression | Death | New 2 | 0 | 59.85813 | 1 | 2.420226 | 14.620259 | 1 | 3 | 3 | 12.200032 |
Stable | Progression | New 2 | 0 | 62.57282 | 2 | 0.000000 | 7.497464 | 0 | 1 | 3 | 7.497464 |
Stable | Death | New 2 | 0 | 62.57282 | 2 | 0.000000 | 7.497464 | 0 | 2 | 3 | 7.497464 |
# Fit multi-state model
n_trans <- max(tmat, na.rm = TRUE)
wei_fits <- vector(length = n_trans, mode = "list")
f <- as.formula(Surv(time, status) ~ factor(strategy_name) + female + age)
for (i in 1:length(wei_fits)){
if (i == 3) f <- update(f, .~.-factor(strategy_name))
wei_fits[[i]] <- flexsurvreg(f, data = onc3,
subset = (transition_id == i),
dist = "weibull")
}
wei_fits <- flexsurvreg_list(wei_fits)
utility_tbl <- stateval_tbl(
data.table(state_id = states$state_id,
mean = c(.8, .6),
se = c(0.02, .05)
),
dist = "beta")
print(utility_tbl)
## state_id mean se
## 1: 1 0.8 0.02
## 2: 2 0.6 0.05
# Medical costs
medcost_tbl <- stateval_tbl(
data.table(state_id = states$state_id,
mean = c(2000, 9500),
se = c(2000, 9500)
),
dist = "gamma")
print(medcost_tbl)
## state_id mean se
## 1: 1 2000 2000
## 2: 2 9500 9500
# Drug costs
n_times <- 2
n_states <- nrow(states)
n_strategies <- nrow(strategies)
n_i <- n_states * n_times
drugcost_dt <- data.table(
strategy_id = rep(strategies$strategy_id, each = n_i),
state_id = rep(rep(states$state_id, each = n_times), n_strategies),
time_start = rep(c(0, 3/12), n_states * n_strategies),
est = c(2000, 2000, 1500, 1200,
12000, 12000, 1500, 1200,
15000, 15000, 1500, 1200)
)
drugcost_tbl <- stateval_tbl(
drugcost_dt,
dist = "fixed")
print(drugcost_tbl)
## strategy_id state_id time_id time_start time_stop est
## 1: 1 1 1 0.00 0.25 2000
## 2: 1 1 2 0.25 Inf 2000
## 3: 1 2 1 0.00 0.25 1500
## 4: 1 2 2 0.25 Inf 1200
## 5: 2 1 1 0.00 0.25 12000
## 6: 2 1 2 0.25 Inf 12000
## 7: 2 2 1 0.00 0.25 1500
## 8: 2 2 2 0.25 Inf 1200
## 9: 3 1 1 0.00 0.25 15000
## 10: 3 1 2 0.25 Inf 15000
## 11: 3 2 1 0.00 0.25 1500
## 12: 3 2 2 0.25 Inf 1200
n_samples <- 1000 # Number of samples for PSA
transmod_data <- expand(hesim_dat,
by = c("strategies", "patients"))
head(transmod_data)
## strategy_id patient_id strategy_name soc new1 new2 age female
## 1: 1 1 SOC 1 0 0 46.26366 1
## 2: 1 2 SOC 1 0 0 50.49314 1
## 3: 1 3 SOC 1 0 0 35.52785 1
## 4: 1 4 SOC 1 0 0 58.88309 0
## 5: 1 5 SOC 1 0 0 53.66930 0
## 6: 1 6 SOC 1 0 0 53.40432 1
transmod <- create_IndivCtstmTrans(wei_fits, transmod_data,
trans_mat = tmat, n = n_samples,
uncertainty = "normal",
clock = "reset",
start_age = patients$age)
# Utility
utilitymod <- create_StateVals(utility_tbl, n = n_samples,
hesim_data = hesim_dat)
# Costs
drugcostmod <- create_StateVals(drugcost_tbl, n = n_samples,
time_reset = TRUE, hesim_data = hesim_dat)
medcostmod <- create_StateVals(medcost_tbl, n = n_samples,
hesim_data = hesim_dat)
costmods <- list(Drug = drugcostmod,
Medical = medcostmod)
ictstm <- IndivCtstm$new(trans_model = transmod,
utility_model = utilitymod,
cost_models = costmods)
ictstm$sim_disease(max_age = 100)
head(ictstm$disprog_)
## sample strategy_id patient_id grp_id from to final time_start time_stop
## 1: 1 1 1 1 1 3 1 0.000000 11.183651
## 2: 1 1 2 1 1 2 0 0.000000 8.058198
## 3: 1 1 2 1 2 3 1 8.058198 12.794488
## 4: 1 1 3 1 1 2 0 0.000000 15.250551
## 5: 1 1 3 1 2 3 1 15.250551 23.791357
## 6: 1 1 4 1 1 3 1 0.000000 6.047286
ictstm$sim_stateprobs(t = seq(0, 30 , 1/12))
head(ictstm$stateprobs_)
## sample strategy_id grp_id state_id t prob
## 1: 1 1 1 1 0.00000000 1.000
## 2: 1 1 1 1 0.08333333 1.000
## 3: 1 1 1 1 0.16666667 1.000
## 4: 1 1 1 1 0.25000000 0.999
## 5: 1 1 1 1 0.33333333 0.998
## 6: 1 1 1 1 0.41666667 0.996
autoplot(ictstm$stateprobs_, labels = labs_indiv,
ci = FALSE)
# QALYs
ictstm$sim_qalys(dr = c(0,.03))
head(ictstm$qalys_)
## sample strategy_id grp_id state_id dr qalys lys
## 1: 1 1 1 1 0 4.933188 6.374648
## 2: 1 1 1 2 0 3.233055 5.255885
## 3: 1 2 1 1 0 5.604984 7.242740
## 4: 1 2 1 2 0 2.683823 4.363013
## 5: 1 3 1 1 0 6.289275 8.126979
## 6: 1 3 1 2 0 2.915707 4.739981
# Costs
ictstm$sim_costs(dr = .03)
head(ictstm$costs_)
## sample strategy_id grp_id state_id dr category costs
## 1: 1 1 1 1 0.03 Drug 11352.373
## 2: 1 1 1 2 0.03 Drug 4691.177
## 3: 1 2 1 1 0.03 Drug 76292.008
## 4: 1 2 1 2 0.03 Drug 3819.849
## 5: 1 3 1 1 0.03 Drug 105209.810
## 6: 1 3 1 2 0.03 Drug 4042.658
ce_sim_ictstm <- ictstm$summarize()
summary(ce_sim_ictstm, labels = labs_indiv) %>%
format() %>%
kable()
Discount rate | Outcome | SOC | New 1 | New 2 |
---|---|---|---|---|
0.00 | QALYs | 7.87 (7.12, 8.60) | 8.59 (7.81, 9.40) | 9.20 (8.42, 10.06) |
0.03 | QALYs | 6.58 (6.03, 7.14) | 7.10 (6.52, 7.69) | 7.52 (6.96, 8.11) |
0.03 | Costs: Drug | 15,352 (14,431, 16,234) | 78,465 (73,854, 83,200) | 105,306 (99,228, 111,686) |
0.03 | Costs: Medical | 46,784 (4,518, 144,256) | 46,222 (4,543, 137,303) | 46,840 (4,746, 143,093) |
0.03 | Costs: total | 62,136 (19,888, 159,037) | 124,687 (82,038, 218,484) | 152,146 (109,625, 245,279) |
hesim_dat$patients <- data.table(
patient_id = 1:4,
grp_id = c(1, 1, 2, 2),
patient_wt = rep(1/4, 4),
age = c(55, 65, 55, 65),
female = c(1, 1, 0, 0),
grp_name = rep(c("Female", "Male"),
each = 2)
)
labs_cohort <- get_labels(hesim_dat)
Parameters are estimated using both individual patient data and summary data: a model is fit for SOC and relative treatment effects are obtained from the literature.
# Estimation data
onc_pfs_os <- as_pfs_os(onc3, patient_vars = c("patient_id", "female", "age",
"strategy_name"))
onc_pfs_os[patient_id %in% c(1, 2)]
## patient_id female age strategy_name pfs_time pfs_status os_status os_time
## 1: 1 0 59.85813 New 2 2.420226 1 1 14.620258
## 2: 2 0 62.57282 New 2 7.497464 0 0 7.497464
# Parameters
## Fit models for SOC
onc_pfs_os_soc <- onc_pfs_os[strategy_name == "SOC"]
fit_pfs_soc_wei <- flexsurv::flexsurvreg(
Surv(pfs_time, pfs_status) ~ female,
data = onc_pfs_os_soc,
dist = "weibull")
fit_os_soc_wei <- flexsurvreg(
Surv(os_time, os_status) ~ female,
data = onc_pfs_os_soc,
dist = "weibull")
psmfit_soc_wei <- partsurvfit(
flexsurvreg_list(pfs = fit_pfs_soc_wei, os = fit_os_soc_wei),
data = onc_pfs_os_soc
)
## Obtain relative treatment effects
## Fit using the "onc_pfs_os" dataset but assume the estimates are
## obtained from the literature for illustrative purposes
### Create dummies
onc_pfs_os[, new1 := ifelse(strategy_name == "New 1", 1, 0)]
onc_pfs_os[, new2 := ifelse(strategy_name == "New 2", 1, 0)]
### Fit models
fit_pfs_wei <- flexsurv::flexsurvreg(
Surv(pfs_time, pfs_status) ~ female + new1 + new2,
data = onc_pfs_os,
dist = "weibull")
fit_os_wei <- flexsurvreg(
Surv(os_time, os_status) ~ female + new1 + new2,
data = onc_pfs_os,
dist = "weibull")
### Extract coefficients (assumed taken from literature)
params_pfs_wei <- create_params(fit_pfs_wei, n = n_samples)
params_os_wei <- create_params(fit_os_wei, n = n_samples)
coef_pfs_wei <- params_pfs_wei$coefs$scale[, c("new1", "new2")]
coef_os_wei <- params_os_wei$coefs$scale[, c("new1", "new2")]
head(coef_pfs_wei)
## new1 new2
## [1,] 0.1814189 0.2654431
## [2,] 0.1390351 0.2907570
## [3,] 0.1298460 0.2307868
## [4,] 0.1729702 0.3143110
## [5,] 0.1988663 0.3179721
## [6,] 0.1305311 0.2261630
# Update drug costs to work with cohort model
drugcost_tbl <- stateval_tbl(
drugcost_dt[time_start == 0][, time_start := NULL],
dist = "fixed")
print(drugcost_tbl)
## strategy_id state_id est
## 1: 1 1 2000
## 2: 1 2 1500
## 3: 2 1 12000
## 4: 2 2 1500
## 5: 3 1 15000
## 6: 3 2 1500
# Input data
survmods_data <- expand(hesim_dat, by = c("strategies", "patients"))
head(survmods_data)
## strategy_id patient_id strategy_name soc new1 new2 grp_id patient_wt age female grp_name
## 1: 1 1 SOC 1 0 0 1 0.25 55 1 Female
## 2: 1 2 SOC 1 0 0 1 0.25 65 1 Female
## 3: 1 3 SOC 1 0 0 2 0.25 55 0 Male
## 4: 1 4 SOC 1 0 0 2 0.25 65 0 Male
## 5: 2 1 New 1 0 1 0 1 0.25 55 1 Female
## 6: 2 2 New 1 0 1 0 1 0.25 65 1 Female
# Parameters
## Parameters for SOC. We obtain a warning because the model did not
## converge during one of the bootstrap samples; this is allowed because
## max_errors = 5 >= 1.
survmods_params <- create_params(psmfit_soc_wei, n = n_samples,
uncertainty = "bootstrap",
max_errors = 5, silent = TRUE)
## Warning in survreg.fit(X, Y, weights, offset, init = init, controlvals = control, : Ran out of iterations and did not
## converge
## Warning in bootstrap.partsurvfit(object, B = n, ...): There were 1 errors when fitting the statistical model during the
## bootstrap procedure.
## "Manually" add relative treatment effects
survmods_params$pfs$coefs$scale <- cbind(survmods_params$pfs$coefs$scale,
coef_pfs_wei)
survmods_params$os$coefs$scale <- cbind(survmods_params$os$coefs$scale,
coef_os_wei)
survmods_params$pfs$coefs$scale[1:2, ]
## (Intercept) female new1 new2
## [1,] 1.784666 -0.1364781 0.1814189 0.2654431
## [2,] 1.776743 -0.1173777 0.1390351 0.2907570
# Combine input data and parameters to create the survival models
survmods_data[, ("(Intercept)") := 1]
survmods <- create_PsmCurves(survmods_params,
input_data = survmods_data)
utilitymod <- create_StateVals(utility_tbl, n = n_samples,
hesim_data = hesim_dat)
drugcostmod <- create_StateVals(drugcost_tbl, n = n_samples,
hesim_data = hesim_dat)
medcostmod <- create_StateVals(medcost_tbl, n = n_samples,
hesim_data = hesim_dat)
costmods <- list(Drug = drugcostmod, Medical = medcostmod)
psm <- Psm$new(survival_models = survmods,
utility_model = utilitymod,
cost_models = costmods)
times <- seq(0, 30, by = .1)
psm$sim_survival(t = times)
head(psm$survival_)
## sample strategy_id patient_id grp_id patient_wt curve t survival
## 1: 1 1 1 1 0.25 1 0.0 1.0000000
## 2: 1 1 1 1 0.25 1 0.1 0.9998540
## 3: 1 1 1 1 0.25 1 0.2 0.9993126
## 4: 1 1 1 1 0.25 1 0.3 0.9982992
## 5: 1 1 1 1 0.25 1 0.4 0.9967670
## 6: 1 1 1 1 0.25 1 0.5 0.9946815
autoplot(psm$survival_,
labels = c(labs_cohort,
list(curve = c("PFS" = 1, "OS" = 2))
),
ci = TRUE, ci_style = "ribbon")
psm$sim_stateprobs()
psm$stateprobs_[sample == 1 & patient_id == 1 & state_id == 2 & t == 12]
## sample strategy_id patient_id grp_id patient_wt state_id t prob
## 1: 1 1 1 1 0.25 2 12 0.3215069
## 2: 1 2 1 1 0.25 2 12 0.3934037
## 3: 1 3 1 1 0.25 2 12 0.4148810
psm$sim_qalys(dr = .03)
psm$sim_costs(dr = .03)
ce_sim_psm <- psm$summarize(by_grp = TRUE)
summary(ce_sim_psm, labels = labs_cohort) %>%
format() %>%
kable()
Group | Discount rate | Outcome | SOC | New 1 | New 2 |
---|---|---|---|---|---|
Female | 0.03 | QALYs | 6.10 (5.55, 6.63) | 6.61 (6.00, 7.22) | 6.96 (6.36, 7.60) |
Female | 0.03 | Costs: Drug | 15,225 (14,629, 15,900) | 66,473 (62,592, 70,188) | 88,466 (83,561, 93,548) |
Female | 0.03 | Costs: Medical | 52,296 (4,435, 180,774) | 52,717 (4,871, 171,715) | 53,138 (5,156, 169,727) |
Female | 0.03 | Costs: total | 67,521 (19,657, 195,939) | 119,189 (70,613, 239,546) | 141,604 (92,445, 260,157) |
Male | 0.03 | QALYs | 6.51 (5.99, 7.08) | 7.05 (6.46, 7.70) | 7.42 (6.81, 8.07) |
Male | 0.03 | Costs: Drug | 16,247 (15,553, 17,004) | 74,027 (69,772, 78,081) | 98,691 (93,156, 104,387) |
Male | 0.03 | Costs: Medical | 52,677 (4,767, 171,325) | 52,709 (5,188, 165,850) | 52,874 (5,417, 162,113) |
Male | 0.03 | Costs: total | 68,924 (20,902, 187,307) | 126,736 (78,810, 238,080) | 151,565 (103,556, 262,961) |
We will first obtain the underlying parameter estimates. A model is fit for SOC and relative treatment effects are obtained from the literature.
# Estimation data
head(onc3p)
## state strategy_name female age patient_id time strategy_id state_id
## 1: Stable New 2 0 59.85813 1 0.000000 3 1
## 2: Progression New 2 0 59.85813 1 2.420226 3 2
## 3: Death New 2 0 59.85813 1 14.620258 3 3
## 4: Stable New 2 0 62.57282 2 0.000000 3 1
## 5: Stable New 2 0 62.57282 2 7.497464 3 1
## 6: Stable SOC 1 61.44379 3 0.000000 1 1
# Fit multi-state model for SOC with msm
qinit <- matrix(0, nrow = 3, ncol = 3)
qinit[1, 2] <- 0.28; qinit[1, 3] <- 0.013; qinit[2, 3] <- 0.10
msm_fit <- msm(state_id ~ time, subject = patient_id,
data = onc3p[strategy_name == "SOC"],
exacttimes = FALSE,
covariates = ~ age + female,
qmatrix = qinit, gen.inits = FALSE)
# Compare model fit with msm using exact times to an exponential model
## msm with exact transition times
tmat2 <- tmat; tmat2[is.na(tmat2)] <- 0
msm_efit <- msm(state_id ~ time, subject = patient_id,
data = onc3p[strategy_name == "SOC"],
qmatrix = tmat2, exacttimes = TRUE)
## flexsurv with exponential model
exp_fits <- vector(length = n_trans, mode = "list")
for (i in 1:length(wei_fits)){
exp_fits[[i]] <- flexsurvreg(Surv(time, status) ~ 1, data = onc3,
subset = (transition_id == i &
strategy_name == "SOC"),
dist = "exponential")
}
## Compare the coefficients
msm_efit
##
## Call:
## msm(formula = state_id ~ time, subject = patient_id, data = onc3p[strategy_name == "SOC"], qmatrix = tmat2, exacttimes = TRUE)
##
## Maximum likelihood estimates
##
## Transition intensities
## Baseline
## Stable - Stable -0.17427 (-0.1880,-0.16155)
## Stable - Progression 0.12999 ( 0.1191, 0.14191)
## Stable - Dead 0.04428 ( 0.0381, 0.05146)
## Progression - Progression -0.09088 (-0.1027,-0.08040)
## Progression - Dead 0.09088 ( 0.0804, 0.10272)
##
## -2 * log-likelihood: 6173.881
## [Note, to obtain old print format, use "printold.msm"]
exp_fits[[1]]$res
## est L95% U95% se
## rate 0.1299939 0.1190743 0.1419149 0.005819325
exp_fits[[2]]$res
## est L95% U95% se
## rate 0.04428652 0.03810548 0.05147018 0.00339662
exp_fits[[3]]$res
## est L95% U95% se
## rate 0.0908797 0.08040199 0.1027228 0.005679981
# Relative treatment effects (i.e., relative risk)
# Assume estimated from external source and simulate distribution
# for PSA
params_rr <- list(
lrr_12_est = c(soc = log(1), new1 = log(.80), new2 = log(.71)),
lrr_12_se = c(soc = 0, new1 = .03, new2 = .04),
lrr_13_est = c(soc = log(1), new1 = log(.90), new2 = log(.85)),
lrr_13_se = c(soc = 0, new1 = .02, new2 = .03)
)
params_rr_def <- define_rng({
list(
rr_12 = lognormal_rng(lrr_12_est, lrr_12_se),
rr_13 = lognormal_rng(lrr_13_est, lrr_13_se)
)}, n = n_samples)
params_rr_rng <- eval_rng(params_rr_def, params_rr)
We now use the underlying parameter estimates and input data to generate the “transformed” parameters.
# Start by predicting transition intensity matrices for each patient
# with SOC. Use a multivariate normal distribution to simulate samples
# for the PSA
transmod_data <- survmods_data
qmat_soc <- qmatrix(msm_fit,
newdata = transmod_data[strategy_name == "SOC"],
uncertainty = "normal", n = n_samples)
dim(qmat_soc)
## [1] 3 3 4000
qmat_soc[,, 1]
## [,1] [,2] [,3]
## [1,] -0.3533989 0.3371267 0.01627226
## [2,] 0.0000000 -0.1190753 0.11907530
## [3,] 0.0000000 0.0000000 0.00000000
# Take the matrix exponential to convert the transition intensity matrices to
# transition probability matrices
cycle_len <- 1/4
pmat_soc <- expmat(qmat_soc, t = cycle_len)
pmat_soc[,, 1]
## [,1] [,2] [,3]
## [1,] 0.9154407 0.07945955 0.00509979
## [2,] 0.0000000 0.97066990 0.02933010
## [3,] 0.0000000 0.00000000 1.00000000
# Align the transition matrices with the ID variables
tpmat_id <- tpmatrix_id(transmod_data, n_samples)
head(tpmat_id)
## sample strategy_id patient_id grp_id patient_wt
## 1: 1 1 1 1 0.25
## 2: 1 1 2 1 0.25
## 3: 1 1 3 2 0.25
## 4: 1 1 4 2 0.25
## 5: 1 2 1 1 0.25
## 6: 1 2 2 1 0.25
# Compute relative risks for each row in the input data and each parameter
# sample for the PSA
xbeta <- function(x, beta) c(x %*% t(beta))
x_rr <- as.matrix(transmod_data[, .(soc, new1, new2)])
rr <- cbind(xbeta(x_rr, params_rr_rng$rr_12),
xbeta(x_rr, params_rr_rng$rr_13))
head(rr) # Corresponds to 1st 6 rows in tpmat_id
## [,1] [,2]
## [1,] 1.000000 1.0000000
## [2,] 1.000000 1.0000000
## [3,] 1.000000 1.0000000
## [4,] 1.000000 1.0000000
## [5,] 0.833283 0.9039595
## [6,] 0.833283 0.9039595
# Apply the relative risks to SOC to get transition probabilities for each
# parameter sample, treatment strategy, and representative patient
pmat <- apply_rr(pmat_soc, rr = rr,
index = list(c(1, 2), c(1, 3)))
tprobs <- tparams_transprobs(pmat, tpmat_id)
transmod <- CohortDtstmTrans$new(params = tprobs,
cycle_length = cycle_len)
cdtstm <- CohortDtstm$new(trans_model = transmod,
utility_model = psm$utility_model,
cost_models = psm$cost_models)
cdtstm$sim_stateprobs(n_cycles = 30/cycle_len)
cdtstm$sim_qalys(dr = .03)
cdtstm$sim_costs(dr = .03)
ce_sim_cdtstm <- cdtstm$summarize()
summary(ce_sim_cdtstm, labels = labs_cohort) %>%
format() %>%
kable()
Discount rate | Outcome | SOC | New 1 | New 2 |
---|---|---|---|---|
0.03 | QALYs | 5.56 (4.78, 6.26) | 5.92 (5.10, 6.67) | 6.14 (5.27, 6.84) |
0.03 | Costs: Drug | 13,862 (12,563, 14,711) | 46,196 (41,201, 50,104) | 60,714 (53,418, 66,584) |
0.03 | Costs: Medical | 62,515 (4,186, 217,838) | 62,011 (4,351, 223,642) | 61,636 (4,671, 213,904) |
0.03 | Costs: total | 76,378 (18,215, 231,236) | 108,207 (50,113, 267,630) | 122,350 (64,868, 274,308) |
# "ce" object to use for analysis
ce_sim_ictstm
## $costs
## category dr sample strategy_id costs grp_id
## 1: Drug 0.03 1 1 16043.55 1
## 2: Drug 0.03 1 2 80111.86 1
## 3: Drug 0.03 1 3 109252.47 1
## 4: Drug 0.03 2 1 14645.16 1
## 5: Drug 0.03 2 2 77962.49 1
## ---
## 8996: total 0.03 999 2 95024.16 1
## 8997: total 0.03 999 3 122357.69 1
## 8998: total 0.03 1000 1 52638.13 1
## 8999: total 0.03 1000 2 119410.47 1
## 9000: total 0.03 1000 3 151164.45 1
##
## $qalys
## dr sample strategy_id qalys grp_id
## 1: 0.00 1 1 8.166243 1
## 2: 0.00 1 2 8.288806 1
## 3: 0.00 1 3 9.204982 1
## 4: 0.00 2 1 7.440970 1
## 5: 0.00 2 2 8.414148 1
## ---
## 5996: 0.03 999 2 7.134710 1
## 5997: 0.03 999 3 7.399217 1
## 5998: 0.03 1000 1 6.435002 1
## 5999: 0.03 1000 2 7.103850 1
## 6000: 0.03 1000 3 7.584523 1
##
## attr(,"class")
## [1] "ce"
wtp <- seq(0, 250000, 500) # Willingness to pay per QALY
cea_ictstm <- cea(ce_sim_ictstm, dr_costs = .03, dr_qalys = .03, k = wtp)
cea_pw_ictstm <- cea_pw(ce_sim_ictstm, comparator = 1,
dr_qalys = .03, dr_costs = .03,
k = wtp)
icer(cea_pw_ictstm, k = 100000, labels = labs_indiv) %>%
format() %>%
kable()
Outcome | New 1 | New 2 |
---|---|---|
Incremental QALYs | 0.52 (0.16, 0.90) | 0.93 (0.58, 1.27) |
Incremental costs | 62,551 (51,685, 70,389) | 90,010 (77,342, 100,581) |
Incremental NMB | -11,003 (-42,132, 21,247) | 3,223 (-28,582, 33,456) |
ICER | 121,345 | 96,543 |
plot_ceplane(cea_pw_ictstm, labels = labs_indiv)
plot_ceac(cea_ictstm, labels = labs_indiv)
plot_ceac(cea_pw_ictstm, labels = labs_indiv)
plot_ceaf(cea_ictstm, labels = labs_indiv)
plot_evpi(cea_ictstm, labels = labs_indiv)
sessionInfo()
## R version 4.0.3 (2020-10-10)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS Mojave 10.14.6
##
## Matrix products: default
## BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib
##
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
##
## attached base packages:
## [1] stats graphics grDevices datasets utils methods base
##
## other attached packages:
## [1] msm_1.6.8 magrittr_2.0.1 knitr_1.31 hesim_0.5.0 ggplot2_3.3.3 flexsurv_1.1.1
## [7] survival_3.2-7 data.table_1.14.0
##
## loaded via a namespace (and not attached):
## [1] Rcpp_1.0.6 highr_0.8 pillar_1.4.7 compiler_4.0.3 RColorBrewer_1.1-2 tools_4.0.3
## [7] digest_0.6.27 evaluate_0.14 lifecycle_1.0.0 tibble_3.0.6 gtable_0.3.0 lattice_0.20-41
## [13] pkgconfig_2.0.3 rlang_0.4.10 Matrix_1.3-2 yaml_2.2.1 mvtnorm_1.1-1 expm_0.999-6
## [19] xfun_0.21 withr_2.4.1 stringr_1.4.0 dplyr_1.0.4 generics_0.1.0 vctrs_0.3.6
## [25] grid_4.0.3 tidyselect_1.1.0 deSolve_1.28 mstate_0.3.1 glue_1.4.2 R6_2.5.0
## [31] rmarkdown_2.7 farver_2.0.3 tidyr_1.1.2 purrr_0.3.4 MASS_7.3-53.1 codetools_0.2-18
## [37] htmltools_0.5.1.1 scales_1.1.1 ellipsis_0.3.1 splines_4.0.3 colorspace_2.0-0 renv_0.12.5
## [43] labeling_0.4.2 quadprog_1.5-8 stringi_1.5.3 muhaz_1.2.6.1 munsell_0.5.0 crayon_1.4.1