使用heemod包构建马尔可夫模型并进行药物经济学分析
TwT的学习笔记,公众号:TwT的R语言学习笔记使用heemod包构建马尔可夫模型并进行药物经济学分析(一)
使用heemod包构建马尔可夫模型并进行药物经济学分析
TwT的学习笔记,公众号:TwT的R语言学习笔记使用heemod包构建马尔可夫模型并进行药物经济学分析(二)
mod_par #查看模型参数,mod_par通过define_parameters()定义,详见第一期
res_mod #查看基线结果,res_mod通过run_model()计算得来,详见第二期
def_dsa <- define_dsa( #将参数输入到def_dsa这个对象中
###接下来根据 参数名称,参数下限,参数上限,的顺序输入
rAE_A, 0.005, 0.02,
rAE_B, 0.04, 0.16,
cAE_A, 400, 600,
cAE_B, 50, 400,
cA, 600, 1100,
cB, ifelse(state_time <= 5, 2000, 0), ifelse(state_time <= 5, 4000, 0),
cC, 30, 70,
cDeath, ifelse(state_time == 1, 14000, 0), ifelse(state_time == 1, 16000, 0),
uAE_A, -0.01, -0.04,
uAE_B, -0.005, -0.02,
uPFS, 0.8, 0.9,
uPD, 0.65, 0.8,
Discount_rate, 0, 0.08)
res_dsa <- run_dsa(res_mod, dsa = def_dsa) #将结果保存到res_dsa对象中
plot(res_dsa,
type = "difference",
result = "icer" #以icer为结果指标
)
install.packages("ggplot2")
library(ggplot2)
res_dsa$dsa #结果保存在res_dsa下的dsa对象中
library(dplyr)
icer_results <- res_dsa$dsa %>%
group_by(.par_names, .par_value, .par_value_eval) %>%
summarize(
ICER = (sum(.cost[.strategy_names == "A"]) - sum(.cost[.strategy_names == "B"])) /
(sum(.effect[.strategy_names == "A"]) - sum(.effect[.strategy_names == "B"]))
) %>%
ungroup()
icer_results
icer_results <- icer_results %>%
group_by(.par_names) %>%
mutate(icer_diff = max(ICER) - min(ICER)) %>%
ungroup() %>%
mutate(order_rank = dense_rank(desc(icer_diff))) %>%
arrange(icer_diff, .par_names) %>% #对ICER影响力最大的参数排在第一
mutate(.par_names = factor(.par_names, levels = unique(.par_names)))
icer_results
ICER_base <-
(res_dsa$model$run_model[
res_dsa$model$run_model$.strategy_names == "A", #A药的Cost
".cost"] - res_dsa$model$run_model[
res_dsa$model$run_model$.strategy_names == "B", #B药的Cost
".cost"]) /
(res_dsa$model$run_model[
res_dsa$model$run_model$.strategy_names == "A", #A药的QALY
".effect"] - res_dsa$model$run_model[
res_dsa$model$run_model$.strategy_names == "B", #A药的QALY
".effect"])
ICER_base
icer_plot_data <- icer_results %>%
mutate(xmin = pmin(ICER, ICER_base), #xmin取ICER和ICER_base中较小的那个
xmax = pmax(ICER, ICER_base), #xmax取ICER和ICER_base中较大的那个
ymin = as.numeric(.par_names) - 0.8 / 2, #ymin取该行的坐标减去一半的单位宽度
ymax = as.numeric(.par_names) + 0.8 / 2) %>% #ymax取该行的坐标减去一半的单位宽度
group_by(.par_names) %>%
mutate(type = ifelse(.par_value_eval == max(.par_value_eval), "Upper Limit", "Lower Limit")) %>%
ungroup()
icer_plot_data
transl <- c("cA" = "Cost of A",
"cB" = "Cost of B",
"cC" = "Cost of C",
"rAE_B" = "AE rate with A",
"rAE_B" = "AE rate with B",
"cAE_A" = "Cost on AEs with A",
"cAE_B" = "Cost on AEs with B",
"cDeath" = "1-time cost on death",
"uPFS" = "PFS utility",
"uPD" = "PD utility",
"Discount_rate" = "Discount rate")
icer_plot_data$.par_names <- recode(icer_plot_data$.par_names, !!!transl)
ggplot(data = icer_plot_data,
aes(y = .par_names)) +
geom_rect(aes(
ymax = ymax,
ymin = ymin,
xmax = xmax,
xmin = xmin,
fill = type
)) +
theme_bw() +
theme(
axis.title.y = element_blank(),
legend.position = c(0.85, 0.15),
legend.title = element_blank(),
text = element_text(size = 10)
) +
geom_vline(xintercept = ICER_base) +
scale_fill_manual(values = c("#008080", "#FF7F50"))
DSA_PLOT <- function(comparison = c(), #输入两个策略的名称
res_dsa = NULL, #输入dsa模型
transl = NULL, #定义更改参数名的规则
colors = c("#008080", "#FF7F50"), #定义龙卷风图的颜色
width = 0.8, #定义龙卷风图中每个矩形的宽
legend.position = c(0.85, 0.15)) { #定义图例的位置
icer_results <- res_dsa$dsa %>%
group_by(.par_names, .par_value, .par_value_eval) %>%
summarize(
ICER = (sum(.cost[.strategy_names == comparison[1]]) - sum(.cost[.strategy_names == comparison[2]])) /
(sum(.effect[.strategy_names == comparison[1]]) - sum(.effect[.strategy_names == comparison[2]]))
) %>%
ungroup()
icer_results <- icer_results %>%
group_by(.par_names) %>%
mutate(icer_diff = max(ICER) - min(ICER)) %>%
ungroup() %>%
mutate(order_rank = dense_rank(desc(icer_diff))) %>%
arrange(icer_diff, .par_names) %>%
mutate(.par_names = factor(.par_names, levels = unique(.par_names)))
ICER_base <-
(res_dsa$model$run_model[
res_dsa$model$run_model$.strategy_names == "A", #A药的Cost
".cost"] - res_dsa$model$run_model[
res_dsa$model$run_model$.strategy_names == "B", #B药的Cost
".cost"]) /
(res_dsa$model$run_model[
res_dsa$model$run_model$.strategy_names == "A", #A药的QALY
".effect"] - res_dsa$model$run_model[
res_dsa$model$run_model$.strategy_names == "B", #A药的QALY
".effect"])
icer_plot_data <- icer_results %>%
mutate(xmin = pmin(ICER, ICER_base), #xmin取ICER和ICER_base中较小的那个
xmax = pmax(ICER, ICER_base), #xmax取ICER和ICER_base中较大的那个
ymin = as.numeric(.par_names) - width / 2, #ymin取该行的坐标减去一半的单位宽度
ymax = as.numeric(.par_names) + width / 2) %>% #ymax取该行的坐标减去一半的单位宽度
group_by(.par_names) %>%
mutate(type = ifelse(.par_value_eval == max(.par_value_eval), "Upper Limit", "Lower Limit")) %>%
ungroup()
icer_plot_data$.par_names <- recode(icer_plot_data$.par_names, !!!transl)
plot <- ggplot(data = icer_plot_data,
aes(y = .par_names)) +
geom_rect(aes(
ymax = ymax,
ymin = ymin,
xmax = xmax,
xmin = xmin,
fill = type
)) +
theme_bw() +
theme(
axis.title.y = element_blank(),
legend.position = legend.position,
legend.title = element_blank(),
text = element_text(size = 10)
) +
geom_vline(xintercept = ICER_base) +
scale_fill_manual(values = colors)
return(plot)
}
transl <- c("cA" = "Cost of A",
"cB" = "Cost of B",
"cC" = "Cost of C",
"rAE_B" = "AE rate with A",
"rAE_B" = "AE rate with B",
"cAE_A" = "Cost on AEs with A",
"cAE_B" = "Cost on AEs with B",
"cDeath" = "1-time cost on death",
"uPFS" = "PFS utility",
"uPD" = "PD utility",
"Discount_rate" = "Discount rate")
plot <- DSA_PLOT(comparison = c("A", "B"),
res_dsa = res_dsa, transl = transl)
plot
ggsave(plot = plot,
filename = "/Path/to/your/csv.csv") #将/Path/to/your/csv.csv替换为你的文件路径
use_cluster(num_cores = 4) #这时填入线程数量,可以根据CPU核心的数量自行调整,但4个线程以上对速度的提升不大
res_dsa <- run_dsa(res_mod, dsa = def_dsa)
close_cluster()
###单线程
start <- Sys.time()
res_dsa <- run_dsa(res_mod, dsa = def_dsa)
end <- Sys.time()
end-start
###多线程
start <- Sys.time()
use_cluster(num_cores = 4) #这时填入线程数量,可以根据CPU核心的数量自行调整,但4个线程以上对速度的提升不大
res_dsa <- run_dsa(res_mod, dsa = def_dsa)
close_cluster()
end <- Sys.time()
end-start
微信扫一扫
关注该公众号