Skip to content

Commit 75acf05

Browse files
committed
Update cSTM_time_indep.R
Simplified code and added comments on where the functions can be found
1 parent 3785839 commit 75acf05

File tree

1 file changed

+63
-50
lines changed

1 file changed

+63
-50
lines changed

analysis/cSTM_time_indep.R

Lines changed: 63 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -39,33 +39,28 @@ rm(list = ls()) # remove any variables in R's memory
3939

4040
### Install packages
4141
# install.packages("dplyr") # to manipulate data
42-
# install.packages("data.table") # to manipulate data
4342
# install.packages("tidyr") # to manipulate data
4443
# install.packages("reshape2") # to manipulate data
4544
# install.packages("ggplot2") # to visualize data
46-
# install.packages("gridExtra") # to visualize data
45+
# install.packages("ggrepel") # to visualize data
46+
# install.packages("ellipse") # to visualize data
4747
# install.packages("scales") # for dollar signs and commas
48-
# install.packages("boot") # to handle log odds and log odds ratios
49-
# install.packages("devtools") # to ensure compatibility among packages
5048
# install.packages("dampack") # for CEA and calculate ICERs
51-
# devtools::install_github("DARTH-git/darthtools") # to install darthtools from GitHub
49+
# install.packages("devtools") # to install packages from GitHub
50+
# devtools::install_github("DARTH-git/darthtools") # to install darthtools from GitHub using devtools
5251
# install.packages("doParallel") # to handle parallel processing
5352

5453
### Load packages
55-
library(dplyr)
56-
library(data.table)
54+
library(dplyr)
5755
library(tidyr)
58-
library(reshape2)
59-
library(ggplot2)
60-
library(ggrepel)
61-
library(ellipse)
62-
library(gridExtra)
63-
library(ggthemes) # For colorblind palettes
64-
library(scales) # For dollar signs and commas
65-
library(boot)
66-
# library(dampack) # Uncomment to use CEA and PSA visualization functionality form dampack instead of the functions included in this repository
67-
library(darthtools) # For WCC, parameter transformation an matrix checks
68-
library(doParallel)
56+
library(reshape2) # For melting data
57+
library(ggplot2) # For plotting
58+
library(ggrepel) # For plotting
59+
library(ellipse) # For plotting
60+
library(scales) # For dollar signs and commas
61+
# library(dampack) # Uncomment to use CEA and PSA visualization functionality from dampack instead of the functions included in this repository
62+
# library(darthtools) # Uncomment to use WCC, parameter transformation, and matrix checks from darthtools instead of the functions included in this repository
63+
# library(doParallel) # For running PSA in parallel
6964

7065
### Load supplementary functions
7166
source("R/Functions.R")
@@ -95,8 +90,8 @@ v_names_str <- c("Standard of care", # store the strategy names
9590
n_str <- length(v_names_str) # number of strategies
9691

9792
# Within-cycle correction (WCC) using Simpson's 1/3 rule
98-
v_wcc <- darthtools::gen_wcc(n_cycles = n_cycles,
99-
method = "Simpson1/3") # vector of wcc
93+
v_wcc <- gen_wcc(n_cycles = n_cycles, # Function included in "R/Functions.R". The latest version can be found in `darthtools` package
94+
method = "Simpson1/3") # vector of wcc
10095

10196
## Transition probabilities (annual), and hazard ratios (HRs)
10297
r_HD <- 0.002 # constant annual rate of dying when Healthy (all-cause mortality)
@@ -133,7 +128,8 @@ v_dwe <- 1 / ((1 + (d_c * cycle_length)) ^ (0:n_cycles))
133128
# compute mortality rates
134129
r_S1D <- r_HD * hr_S1 # annual mortality rate in the Sick state
135130
r_S2D <- r_HD * hr_S2 # annual mortality rate in the Sicker state
136-
# transform rates to probabilities
131+
# transform rates to probabilities
132+
# Function included in "R/Functions.R". The latest version can be found in `darthtools` package
137133
p_HS1 <- rate_to_prob(r = r_HS1, t = cycle_length) # constant annual probability of becoming Sick when Healthy conditional on surviving
138134
p_S1H <- rate_to_prob(r = r_S1H, t = cycle_length) # constant annual probability of becoming Healthy when Sick conditional on surviving
139135
p_S1S2 <- rate_to_prob(r = r_S1S2, t = cycle_length)# constant annual probability of becoming Sicker when Sick conditional on surviving
@@ -147,7 +143,7 @@ r_S1S2_trtB <- r_S1S2 * hr_S1S2_trtB
147143
# transform rate to probability
148144
# probability to become Sicker when Sick
149145
# under treatment B conditional on surviving
150-
p_S1S2_trtB <- rate_to_prob(r = r_S1S2_trtB, t = cycle_length)
146+
p_S1S2_trtB <- rate_to_prob(r = r_S1S2_trtB, t = cycle_length) # Function included in "R/Functions.R". The latest version can be found in `darthtools` package
151147

152148
####################### Construct state-transition models ######################
153149
## Initial state vector
@@ -202,16 +198,17 @@ m_P_strB["S1", "S2"] <- (1 - p_S1D) * p_S1S2_trtB
202198
m_P_strAB <- m_P_strB
203199

204200
### Check if transition probability matrices are valid
201+
# Functions included in "R/Functions.R". The latest version can be found in `darthtools` package
205202
## Check that transition probabilities are [0, 1]
206-
darthtools::check_transition_probability(m_P, verbose = TRUE) # m_P >= 0 && m_P <= 1
207-
darthtools::check_transition_probability(m_P_strA, verbose = TRUE) # m_P_strA >= 0 && m_P_strA <= 1
208-
darthtools::check_transition_probability(m_P_strB, verbose = TRUE) # m_P_strB >= 0 && m_P_strB <= 1
209-
darthtools::check_transition_probability(m_P_strAB, verbose = TRUE) # m_P_strAB >= 0 && m_P_strAB <= 1
203+
check_transition_probability(m_P, verbose = TRUE) # m_P >= 0 && m_P <= 1
204+
check_transition_probability(m_P_strA, verbose = TRUE) # m_P_strA >= 0 && m_P_strA <= 1
205+
check_transition_probability(m_P_strB, verbose = TRUE) # m_P_strB >= 0 && m_P_strB <= 1
206+
check_transition_probability(m_P_strAB, verbose = TRUE) # m_P_strAB >= 0 && m_P_strAB <= 1
210207
## Check that all rows sum to 1
211-
darthtools::check_sum_of_transition_array(m_P, n_states = n_states, n_cycles = n_cycles, verbose = TRUE) # rowSums(m_P) == 1
212-
darthtools::check_sum_of_transition_array(m_P_strA, n_states = n_states, n_cycles = n_cycles, verbose = TRUE) # rowSums(m_P_strA) == 1
213-
darthtools::check_sum_of_transition_array(m_P_strB, n_states = n_states, n_cycles = n_cycles, verbose = TRUE) # rowSums(m_P_strB) == 1
214-
darthtools::check_sum_of_transition_array(m_P_strAB, n_states = n_states, n_cycles = n_cycles, verbose = TRUE) # rowSums(m_P_strAB) == 1
208+
check_sum_of_transition_array(m_P, n_states = n_states, n_cycles = n_cycles, verbose = TRUE) # rowSums(m_P) == 1
209+
check_sum_of_transition_array(m_P_strA, n_states = n_states, n_cycles = n_cycles, verbose = TRUE) # rowSums(m_P_strA) == 1
210+
check_sum_of_transition_array(m_P_strB, n_states = n_states, n_cycles = n_cycles, verbose = TRUE) # rowSums(m_P_strB) == 1
211+
check_sum_of_transition_array(m_P_strAB, n_states = n_states, n_cycles = n_cycles, verbose = TRUE) # rowSums(m_P_strAB) == 1
215212

216213
####################### Run Markov model #######################
217214
# Iterative solution of time-independent cSTM
@@ -235,7 +232,7 @@ names(l_m_M) <- v_names_str
235232

236233
#### Plot Outputs ####
237234
### Plot the cohort trace for strategies SoC and A
238-
plot_trace(m_M)
235+
plot_trace(m_M) # Function included in "R/Functions.R"; depends on the `ggplot2` package
239236

240237
#### State Rewards scaled by the cycle length ####
241238
## Vector of state utilities under strategy SoC
@@ -317,17 +314,21 @@ for (i in 1:n_str) {
317314

318315
########################### Cost-effectiveness analysis ########################
319316
### Calculate incremental cost-effectiveness ratios (ICERs)
317+
# Function included in "R/Functions.R"; depends on the `dplyr` package
318+
# The latest version can be found in `dampack` package
320319
df_cea <- calculate_icers(cost = v_tot_cost,
321320
effect = v_tot_qaly,
322321
strategies = v_names_str)
323322
df_cea
324323

325324
### Create CEA table in proper format
326-
table_cea <- format_table_cea(df_cea)
325+
table_cea <- format_table_cea(df_cea) # Function included in "R/Functions.R"; depends on the `scales` package
327326
table_cea
328327

329328
### CEA frontier
330-
plot(df_cea, label = "all") +
329+
# Function included in "R/Functions.R"; depends on the `ggplot2` and `ggrepel` packages.
330+
# The latest version can be found in `dampack` package
331+
plot.icers(df_cea, label = "all") +
331332
expand_limits(x = max(table_cea$QALYs) + 0.1)
332333

333334
################### Probabilistic Sensitivity Analysis (PSA) ###################
@@ -388,7 +389,8 @@ df_psa_input <- generate_psa_params(n_sim = n_sim)
388389
head(df_psa_input)
389390

390391
# Histogram of parameters
391-
ggplot(melt(df_psa_input, variable.name = "Parameter"), aes(x = value)) +
392+
ggplot(melt(df_psa_input, variable.name = "Parameter"),
393+
aes(x = value)) +
392394
facet_wrap(~Parameter, scales = "free") +
393395
geom_histogram(aes(y = ..density..)) +
394396
scale_x_continuous(breaks = number_ticks(4)) +
@@ -427,7 +429,7 @@ for(i in 1:n_sim){
427429
}
428430
n_time_end_psa_series <- Sys.time()
429431
n_time_total_psa_series <- n_time_end_psa_series - n_time_init_psa_series
430-
print(paste0("PSA with ", comma(n_sim), " simulations run in series in ",
432+
print(paste0("PSA with ", scales::comma(n_sim), " simulations run in series in ",
431433
round(n_time_total_psa_series, 2), " ",
432434
units(n_time_total_psa_series)))
433435

@@ -496,12 +498,13 @@ print(paste0("PSA with ", comma(n_sim), " simulations run in series in ",
496498
# # Stop clusters
497499
# stopCluster(cl)
498500
# n_time_total_psa <- n_time_end_psa - n_time_init_psa
499-
# print(paste0("PSA with ", comma(n_sim), " simulations run in series in ",
501+
# print(paste0("PSA with ", scales:: comma(n_sim), " simulations run in series in ",
500502
# round(n_time_total_psa, 2), " ",
501503
# units(n_time_total_psa_series)))
502504

503505
## Visualize PSA results and CEA
504-
# Create PSA object for dampack
506+
## Create PSA object
507+
# Function included in "R/Functions.R" The latest version can be found in `dampack` package
505508
l_psa <- make_psa_obj(cost = df_c,
506509
effectiveness = df_e,
507510
parameters = df_psa_input,
@@ -514,42 +517,51 @@ colnames(l_psa$cost)<- v_names_str
514517
# Vector with willingness-to-pay (WTP) thresholds.
515518
v_wtp <- seq(0, 200000, by = 5000)
516519

517-
# Cost-Effectiveness Scatter plot
518-
plot(l_psa) +
520+
## Cost-Effectiveness Scatter plot
521+
# Function included in "R/Functions.R"; depends on `tidyr` and `ellipse` packages.
522+
# The latest version can be found in `dampack` package
523+
plot.psa(l_psa) +
519524
ggthemes::scale_color_colorblind() +
520525
ggthemes::scale_fill_colorblind() +
521526
xlab("Effectiveness (QALYs)") +
522527
guides(col = guide_legend(nrow = 2)) +
523528
theme(legend.position = "bottom")
524529

525-
# Conduct CEA with probabilistic output
530+
## Conduct CEA with probabilistic output
526531
# Compute expected costs and effects for each strategy from the PSA
527-
df_out_ce_psa <- summary(l_psa)
532+
# Function included in "R/Functions.R". The latest version can be found in `dampack` package
533+
df_out_ce_psa <- summary.psa(l_psa)
528534

529535
# Calculate incremental cost-effectiveness ratios (ICERs)
536+
# Function included in "R/Functions.R"; depends on the `dplyr` package
537+
# The latest version can be found in `dampack` package
530538
df_cea_psa <- calculate_icers(cost = df_out_ce_psa$meanCost,
531539
effect = df_out_ce_psa$meanEffect,
532540
strategies = df_out_ce_psa$Strategy)
533541
df_cea_psa
534542

535-
# Plot cost-effectiveness frontier
536-
plot(df_cea_psa)
543+
## Plot cost-effectiveness frontier
544+
# Function included in "R/Functions.R"; depends on the `ggplot2` and `ggrepel` packages.
545+
# The latest version can be found in `dampack` package
546+
plot.icers(df_cea_psa)
537547

538-
# Cost-effectiveness acceptability curves (CEACs) and frontier (CEAF)
548+
#### Cost-effectiveness acceptability curves (CEACs) and frontier (CEAF) #####
549+
# Functions included in "R/Functions.R". The latest versions can be found in `dampack` package
539550
ceac_obj <- ceac(wtp = v_wtp, psa = l_psa)
540551
# Regions of highest probability of cost-effectiveness for each strategy
541-
summary(ceac_obj)
552+
summary.ceac(ceac_obj)
542553
# CEAC & CEAF plot
543-
plot(ceac_obj) +
554+
plot.ceac(ceac_obj) +
544555
ggthemes::scale_color_colorblind() +
545556
ggthemes::scale_fill_colorblind() +
546557
theme(legend.position = c(0.82, 0.5))
547558

548-
# Expected Loss Curves (ELCs)
559+
#### Expected Loss Curves (ELCs) ####
560+
# Function included in "R/Functions.R".The latest version can be found in `dampack` package
549561
elc_obj <- calc_exp_loss(wtp = v_wtp, psa = l_psa)
550562
elc_obj
551563
# ELC plot
552-
plot(elc_obj, log_y = FALSE,
564+
plot.exp_loss(elc_obj, log_y = FALSE,
553565
txtsize = 16, xlim = c(0, NA), n_x_ticks = 14,
554566
col = "full") +
555567
ggthemes::scale_color_colorblind() +
@@ -560,7 +572,8 @@ plot(elc_obj, log_y = FALSE,
560572
labels = function(x) x/1000) +
561573
theme(legend.position = c(0.4, 0.7))
562574

563-
# Expected value of perfect information (EVPI)
575+
#### Expected value of perfect information (EVPI) ####
576+
# Function included in "R/Functions.R". The latest version can be found in `dampack` package
564577
evpi <- calc_evpi(wtp = v_wtp, psa = l_psa)
565578
# EVPI plot
566-
plot(evpi, effect_units = "QALY")
579+
plot.evpi(evpi, effect_units = "QALY")

0 commit comments

Comments
 (0)