# --- Parameters for the illustration ---
p_vals <- seq(0, 1, 0.01) # mean outbreak probability
R_vals <- c(5)
r_vals <- c(0.3, 0.7)
nu_val <- 0.9
df_cost <- expand.grid(
p = p_vals,
r = r_vals,
R = R_vals
) |>
dplyr::mutate(
c_pre = cost_pre_one(p, R, r, nu = nu_val),
c_react = cost_react_one(p, R, r, nu = nu_val),
r_label = paste0("italic(r)==", r)
) |>
tidyr::pivot_longer(
cols = c(c_pre, c_react),
names_to = "strategy",
values_to = "cost"
) |>
dplyr::mutate(
strategy = factor(
strategy,
levels = c("c_pre", "c_react"),
labels = c(paste0("Pre-emptive (\u03bd=", nu_val, ")"), "Reactive")
)
)
# threshold probability
# df_pstar <- expand.grid(r = r_vals, R = R_vals) |>
# dplyr::mutate(
# p_star = p_star_one(R, r),
# r_label = paste0("r = ", r)
# )
df_pstar <- expand.grid(r = r_vals, R = R_vals) |>
dplyr::mutate(
p_star = p_star_one(R, r, nu = nu_val),
r_label = paste0("r = ", r),
# [NEW] Create the dynamic label string here
# ~ adds a space, italic(r)==r adds the value
label_expr = paste0("italic(p)[crit]^(1) ~ (italic(r) == ", r, ")")
)
# data for braces
cost_preempt_max <- max(filter(df_cost, strategy == paste0("Pre-emptive (\u03bd=", nu_val, ")"), r_label == "italic(r)==0.3")$cost)
cost_react_max1 <- max(filter(df_cost, strategy == "Reactive", r_label == "italic(r)==0.7")$cost)
cost_react_max2 <- max(filter(df_cost, strategy == "Reactive", r_label == "italic(r)==0.3")$cost)
df_brace1 <- data.frame(x = c(0.96, 1), y = c(cost_preempt_max, cost_react_max1))
df_brace2 <- data.frame(x = c(0.97, 1), y = c(cost_preempt_max, cost_react_max2))
df_brace3 <- data.frame(x = c(0, 0.03), y = c(0, 1))
# convenient variables for the overhead-cost text position
text_overhead_x <- max(df_brace3$x) + 0.01 # 0.04
text_overhead_y <- mean(df_brace3$y) + 1 # 1.5
annot_text_size <- 4
ggplot(df_cost, aes(
x = p, y = cost, color = strategy,
linetype = r_label
)) +
geom_line(linewidth = 1) +
geom_vline(
data = df_pstar,
aes(xintercept = p_star),
linetype = "dashed",
color = "firebrick"
) +
geom_text(
data = df_pstar,
aes(x = p_star, y = Inf, label = label_expr),
parse = TRUE,
inherit.aes = FALSE,
hjust = -0.03,
vjust = 1.1,
size = 4
) +
ggbrace::stat_brace(
data = df_brace1,
mapping = aes(x, y),
outside = FALSE, rotate = 270,
linewidth = 1, inherit.aes = FALSE
) +
annotate("text",
x = min(df_brace1$x) - 0.01,
y = mean(df_brace1$y),
label = "Cost of delayed\nresponse (r=0.7)",
hjust = 1, size = annot_text_size, lineheight = 0.9
) +
ggbrace::stat_brace(
data = df_brace2,
mapping = aes(x, y),
outside = FALSE, rotate = 270,
linewidth = 1, inherit.aes = FALSE
) +
annotate("text",
x = min(df_brace2$x) - 0.01, y = mean(df_brace2$y),
label = "Cost of delayed\nresponse (r=0.3)",
hjust = 1, size = annot_text_size, lineheight = 0.9
) +
ggbrace::stat_brace(
data = df_brace3,
mapping = aes(x, y),
outside = FALSE, rotate = 90,
linewidth = 1, inherit.aes = FALSE
) +
annotate("text",
x = max(df_brace3$x) + 0.01,
y = mean(df_brace3$y) + 1,
label = "Vaccination cost",
hjust = 0, size = annot_text_size, lineheight = 0.9
) +
annotate("segment",
x = text_overhead_x + 0.03,
y = text_overhead_y - 0.1,
xend = 0.02, yend = 0.75,
arrow = arrow(length = grid::unit(0.15, "cm")),
colour = "black"
) +
scale_color_manual("", values = c("firebrick", "steelblue")) +
scale_linetype_discrete(labels = scales::label_parse()) +
labs(
x = expression("Probability of an outbreak " ~ italic(p)),
y = expression("Normalized per-population expected cost " ~ italic(c)[s]^"(1)"),
color = "",
linetype = ""
) +
theme_light() +
theme(legend.position = "top") +
guides(
linetype = guide_legend(
override.aes = list(color = "steelblue")
)
)