Executive Summary

This analysis presents a Markov model for evaluating malaria intervention strategies in children under 5 years across urban and rural settings in sub-Saharan Africa. The model compares four intervention strategies across urban and rural settings in children under 5 years old.

NOTE: The parameters to be updated with country-specific data.

Interventions Being Compared The analysis evaluates four intervention strategies (all layered on top of ITNs as baseline prevention):

Strategy Target Population Efficacy Cost Key Features Baseline (ITNs only) Universal 45% against transmission $2.50 per net Current standard of care SMC + ITNs Children 2-5 years 85% against clinical malaria $6.00 per child/year 4 cycles during rainy season Vaccine + ITNs Children 0-24 months 30% infection, 70% severe $26.00 for 4 doses RTS,S/AS01 vaccine Combined Strategy All ages (layered) Synergistic effect Rural multiplier: 1.5× Maximal intervention

Model Overview

Time horizon: 10 years

Cohort size: 10,000 children (scaled from birth to age 5+)

Discount rate: 3% per annum for both costs and health outcomes (DALYs)

Perspective: Healthcare system (direct medical costs + intervention delivery)

Outcomes: Clinical cases, severe cases, deaths, DALYs (discounted), costs (discounted)

# Clear environment to prevent conflicts from previous runs
rm(list = ls())

# Force garbage collection to free memory
gc()
##           used (Mb) gc trigger (Mb) limit (Mb) max used (Mb)
## Ncells  619665 33.1    1417724 75.8         NA   700248 37.4
## Vcells 1187361  9.1    8388608 64.0      49152  1963297 15.0
# Load required packages for analysis and visualization
library(ggplot2)      # For creating publication-quality plots
library(dplyr)        # For data manipulation and aggregation
library(tidyr)        # For reshaping data between wide/long formats
library(knitr)        # For dynamic report generation
library(kableExtra)   # For enhanced table formatting

# Set random seed for reproducibility
set.seed(2026)

# Helper function for formatted numbers with commas
format_number <- function(x) {
  result <- ifelse(is.na(x) | is.infinite(x), "NA", 
                   format(round(x, 0), big.mark = ",", scientific = FALSE))
  return(result)
}

cat("✓ Environment setup complete\n")
## ✓ Environment setup complete
cat("✓ All packages loaded successfully\n")
## ✓ All packages loaded successfully

Model Structure

# ===================================================================
# MARKOV MODEL DIAGRAM
# ===================================================================

# Load required packages
if(!require(diagram)) {
  install.packages("diagram")
  library(diagram)
}

# Create a new plot
# Using plot.new() to initialize the plotting area
plot.new()

# Set up plotting parameters
par(mar = c(2, 2, 3, 2), bg = "white")

# Define state positions (normalized coordinates 0-1)
pos <- rbind(
  c(0.5, 0.85),  # Susceptible (top center)
  c(0.5, 0.60),  # Clinical (middle center)
  c(0.30, 0.35), # Severe (bottom left)
  c(0.70, 0.35)  # Death (bottom right)
)

# Define colors for states and transitions
state_colors <- c(
  "Susceptible" = "#A8E6A3",
  "Clinical" = "#FFD3B6",
  "Severe" = "#FF8B94",
  "Death" = "#AAAAAA"
)

transition_colors <- c(
  "progression" = "#E41A1C",
  "mortality" = "#000000",
  "recovery" = "#377EB8"
)

# State names (with line breaks)
states <- c(
  "Susceptible\n(Uninfected)", 
  "Clinical Malaria\n(Non-severe)", 
  "Severe Malaria", 
  "Death"
)

# ==============================================
# DRAW TRANSITIONS
# ==============================================

# 1. Susceptible → Clinical (disease progression)
straightarrow(
  from = pos[1, ], to = pos[2, ], 
  lwd = 2.5, arr.pos = 0.6, arr.type = "triangle",
  lcol = transition_colors["progression"],
  arr.col = transition_colors["progression"]
)

# Add label for this transition
textrect(
  mid = c(0.55, 0.72), radx = 0.10, rady = 0.025,
  lab = expression(bold(paste("Infection x", delta[clinical]))),
  cex = 0.85, shadow.size = 0, box.col = "white",
  col = transition_colors["progression"]
)

# 2. Clinical → Severe (progression to severe disease)
straightarrow(
  from = pos[2, ], to = pos[3, ], 
  lwd = 2.5, arr.pos = 0.6, arr.type = "triangle",
  lcol = transition_colors["progression"],
  arr.col = transition_colors["progression"]
)

# Add label for this transition
textrect(
  mid = c(0.35, 0.47), radx = 0.08, rady = 0.025,
  lab = expression(bold(delta[severe])),
  cex = 0.85, shadow.size = 0, box.col = "white",
  col = transition_colors["progression"]
)

# 3. Severe → Death (mortality)
straightarrow(
  from = pos[3, ], to = pos[4, ], 
  lwd = 2.5, arr.pos = 0.6, arr.type = "triangle",
  lcol = transition_colors["mortality"],
  arr.col = transition_colors["mortality"]
)

# Add label for this transition
textrect(
  mid = c(0.5, 0.25), radx = 0.10, rady = 0.025,
  lab = expression(bold(paste("Case fatality = CFR"))),
  cex = 0.85, shadow.size = 0, box.col = "white",
  col = transition_colors["mortality"]
)

# 4. Clinical → Susceptible (recovery with immunity)
curvedarrow(
  from = pos[2, ], to = pos[1, ], 
  lwd = 2.5, arr.pos = 0.6, curve = -0.4,
  lcol = transition_colors["recovery"],
  arr.col = transition_colors["recovery"],
  arr.type = "triangle"
)

# Add label for recovery with immunity
textrect(
  mid = c(0.30, 0.78), radx = 0.12, rady = 0.025,
  lab = "Recovery +\nImmunity",
  cex = 0.80, shadow.size = 0, box.col = "#A8E6A3",
  col = transition_colors["recovery"], font = 2
)

# 5. Severe → Susceptible (recovery from severe)
curvedarrow(
  from = pos[3, ], to = pos[1, ], 
  lwd = 2.5, arr.pos = 0.6, curve = -0.5,
  lcol = transition_colors["recovery"],
  arr.col = transition_colors["recovery"],
  arr.type = "triangle"
)

# Add label for recovery from severe
textrect(
  mid = c(0.12, 0.60), radx = 0.10, rady = 0.025,
  lab = "Recovery",
  cex = 0.85, shadow.size = 0, box.col = "#A8E6A3",
  col = transition_colors["recovery"], font = 2
)

# ==============================================
# DRAW STATE BOXES
# ==============================================

# 1. Susceptible state (top)
textrect(
  mid = pos[1, ], radx = 0.15, rady = 0.07,
  lab = states[1], cex = 1.0, shadow.size = 0.01,
  box.col = state_colors["Susceptible"], col = "white",
  lwd = 3, font = 2
)

# 2. Clinical state (middle)
textrect(
  mid = pos[2, ], radx = 0.15, rady = 0.07,
  lab = states[2], cex = 1.0, shadow.size = 0.01,
  box.col = state_colors["Clinical"], col = "white",
  lwd = 3, font = 2
)

# 3. Severe state (bottom left)
textrect(
  mid = pos[3, ], radx = 0.13, rady = 0.07,
  lab = states[3], cex = 1.0, shadow.size = 0.01,
  box.col = state_colors["Severe"], col = "white",
  lwd = 3, font = 2
)

# 4. Death state (bottom right)
textrect(
  mid = pos[4, ], radx = 0.12, rady = 0.07,
  lab = states[4], cex = 1.0, shadow.size = 0.01,
  box.col = state_colors["Death"], col = "white",
  lwd = 3, font = 2
)

# ==============================================
# ADD TITLE AND ANNOTATIONS
# ==============================================

# Main title
title(
  main = "Markov Model Structure for Malaria Progression",
  cex.main = 1.4, line = 0.8, font.main = 2
)

# Subtitle
text(
  x = 0.5, y = 0.96,
  labels = "Monthly transitions with time-dependent discounting (3% annually)",
  cex = 0.85, font = 3, col = "#555555"
)

# ==============================================
# ADD LEGEND AT TOP RIGHT
# ==============================================

legend(
  x = 1.2, y = 0.75,
  legend = c("Disease progression", "Mortality", "Recovery"),
  col = c(
    transition_colors["progression"],
    transition_colors["mortality"],
    transition_colors["recovery"]
  ),
  lwd = 3, cex = 0.85, bty = "o", bg = "white",
  box.col = "black", title = "Transition Types",
  horiz = FALSE, xjust = 1, yjust = 1
)

# ==============================================
# ADD DISCOUNTING NOTE AT BOTTOM LEFT
# ==============================================

text(
  x = 0.02, y = 0.08,
  labels = "NOTE: Only costs and DALYs are discounted (3% annually)",
  cex = 0.75, col = "#E41A1C", adj = 0, font = 2
)

text(
  x = 0.02, y = 0.05,
  labels = "Clinical cases, severe cases, and deaths are NOT discounted",
  cex = 0.70, col = "#E41A1C", adj = 0, font = 2
)

# ==============================================
# ADD ARROW ANNOTATIONS
# ==============================================

# Add explanatory text for recovery arrow
text(
  x = 0.18, y = 0.72,
  labels = "Recovery with\npartial immunity",
  cex = 0.70, col = "#377EB8", adj = 0, font = 3
)

# Add explanatory text for severe recovery
text(
  x = 0.08, y = 0.48,
  labels = "Recovery from\nsevere malaria",
  cex = 0.70, col = "#377EB8", adj = 0, font = 3
)

cat("\n✓ Markov diagram created successfully\n")
## 
## ✓ Markov diagram created successfully

Part 1: Model Parameters

Geographic and Demographic Settings- To be updated

# ===================================================================
# STEP 2: DEFINE GEOGRAPHIC AND DEMOGRAPHIC PARAMETERS
# ===================================================================

# Geographic strata reflecting transmission heterogeneity
geo_settings <- c("Urban", "Rural")
geo_pop_weights <- c(0.30, 0.70)  # 30% urban, 70% rural population distribution

# Geographic-specific parameters
geo_params <- list(
  Urban = list(
    eir_multiplier = 0.4,           # Lower transmission intensity
    itn_coverage = 0.70,            # Higher ITN access
    vaccine_coverage = 0.65,        # Higher vaccine uptake
    smc_coverage = 0.55,            # Moderate SMC coverage
    cfr_multiplier = 1.0,           # Baseline case fatality
    access_delay_days = 0.5         # Rapid healthcare access
  ),
  Rural = list(
    eir_multiplier = 2.0,           # Higher transmission (5x urban)
    itn_coverage = 0.45,            # Lower ITN coverage
    vaccine_coverage = 0.40,        # Lower vaccine coverage
    smc_coverage = 0.45,            # Lower SMC coverage
    cfr_multiplier = 1.6,           # 60% higher case fatality
    access_delay_days = 4.5         # Delayed healthcare access
  )
)

# Display parameter table
geo_params_df <- data.frame(
  Parameter = c("EIR Multiplier", "ITN Coverage", "Vaccine Coverage", 
                "SMC Coverage", "CFR Multiplier", "Access Delay (days)"),
  Urban = c(geo_params$Urban$eir_multiplier,
            geo_params$Urban$itn_coverage,
            geo_params$Urban$vaccine_coverage,
            geo_params$Urban$smc_coverage,
            geo_params$Urban$cfr_multiplier,
            geo_params$Urban$access_delay_days),
  Rural = c(geo_params$Rural$eir_multiplier,
            geo_params$Rural$itn_coverage,
            geo_params$Rural$vaccine_coverage,
            geo_params$Rural$smc_coverage,
            geo_params$Rural$cfr_multiplier,
            geo_params$Rural$access_delay_days)
)

kable(geo_params_df, caption = "Geographic Parameters by Setting",
      digits = 2, format = "html") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
Geographic Parameters by Setting
Parameter Urban Rural
EIR Multiplier 0.40 2.00
ITN Coverage 0.70 0.45
Vaccine Coverage 0.65 0.40
SMC Coverage 0.55 0.45
CFR Multiplier 1.00 1.60
Access Delay (days) 0.50 4.50

Age Group Definitions

# Age groups reflecting key epidemiological periods
age_groups <- c("0-6m", "6-24m", "2-5y", "5+")
age_weights <- c(0.05, 0.11, 0.16, 0.68)

age_params_df <- data.frame(
  Age_Group = age_groups,
  Population_Weight = age_weights,
  Clinical_Risk = c(0.25, 0.20, 0.10, 0.04),
  Severe_Risk = c(0.08, 0.06, 0.02, 0.005),
  CFR_Base = c(0.18, 0.12, 0.06, 0.03),
  VE_Infection = c(0.25, 0.35, 0.25, 0.15),
  VE_Severe = c(0.60, 0.75, 0.65, 0.50)
)

kable(age_params_df, caption = "Age-Specific Parameters",
      digits = 3, format = "html") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
Age-Specific Parameters
Age_Group Population_Weight Clinical_Risk Severe_Risk CFR_Base VE_Infection VE_Severe
0-6m 0.05 0.25 0.080 0.18 0.25 0.60
6-24m 0.11 0.20 0.060 0.12 0.35 0.75
2-5y 0.16 0.10 0.020 0.06 0.25 0.65
5+ 0.68 0.04 0.005 0.03 0.15 0.50

Epidemiological and Cost Parameters

# Epidemiological parameters
base_eir <- 25                    # Baseline EIR: 25 infectious bites/person/year
smc_efficacy <- 0.85              # SMC reduces clinical malaria by 85%
vaccine_ve_infection <- 0.30      # RTS,S efficacy against clinical infection
vaccine_ve_severe <- 0.70         # RTS,S efficacy against severe disease
itn_efficacy <- 0.45              # ITNs reduce transmission by 45%

# Cost parameters (2024 USD)
cost_vaccine_full <- 26.00        # Full 4-dose series per child
cost_smc_per_child_per_year <- 6.00  # 4 cycles at $1.50 per cycle
cost_act <- 1.50                  # Artemisinin combination therapy course
cost_outpatient <- 8.00           # Outpatient visit (clinical case)
cost_hospital <- 150.00           # Hospitalization (severe case)

# DALY parameters (GBD 2021)
dw_clinical <- 0.006              # Disability weight for uncomplicated malaria
dw_severe <- 0.133                # Disability weight for severe malaria
duration_clinical_years <- 14/365  # 14 days duration
duration_severe_years <- 21/365    # 21 days duration
life_expectancy <- 65              # Standard for sub-Saharan Africa

# Discounting
discount_rate <- 0.03             # 3% per annum

# Create summary table
params_summary <- data.frame(
  Parameter = c("Baseline EIR", "SMC Efficacy", "Vaccine VE (Infection)",
                "Vaccine VE (Severe)", "ITN Efficacy", "Vaccine Cost (Full Series)",
                "SMC Cost (Annual)", "ACT Treatment Cost", "Outpatient Visit",
                "Hospitalization", "DALY Weight (Clinical)", "DALY Weight (Severe)",
                "Life Expectancy", "Discount Rate"),
  Value = c(base_eir, smc_efficacy, vaccine_ve_infection,
            vaccine_ve_severe, itn_efficacy, 
            paste0("$", cost_vaccine_full),
            paste0("$", cost_smc_per_child_per_year),
            paste0("$", cost_act), paste0("$", cost_outpatient),
            paste0("$", cost_hospital), dw_clinical, dw_severe,
            life_expectancy, paste0(discount_rate * 100, "%"))
)

kable(params_summary, caption = "Base Model Parameters",
      format = "html") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
Base Model Parameters
Parameter Value
Baseline EIR 25
SMC Efficacy 0.85
Vaccine VE (Infection) 0.3
Vaccine VE (Severe) 0.7
ITN Efficacy 0.45
Vaccine Cost (Full Series) $26
SMC Cost (Annual) $6
ACT Treatment Cost $1.5
Outpatient Visit $8
Hospitalization $150
DALY Weight (Clinical) 0.006
DALY Weight (Severe) 0.133
Life Expectancy 65
Discount Rate 3%
cat("\n✓ Parameters loaded successfully\n")
## 
## ✓ Parameters loaded successfully
cat(sprintf("✓ Discount rate: %.0f%% per annum (applied to COSTS and DALYs ONLY)\n", discount_rate * 100))
## ✓ Discount rate: 3% per annum (applied to COSTS and DALYs ONLY)
cat("✓ Clinical cases, severe cases, and deaths are NOT discounted\n")
## ✓ Clinical cases, severe cases, and deaths are NOT discounted

Part 2: Markov Model Implementation

# ===================================================================
# STEP 8: MAIN MODEL FUNCTION - RUNS MARKOV SIMULATION
# ===================================================================
# NOTE: Only costs and DALYs are discounted at 3% per annum
# Clinical cases, severe cases, and deaths are reported as undiscounted counts

# Main model function
run_stable_model <- function(intervention = "baseline", 
                            time_horizon_years = 10,
                            cohort_size = 10000) {
  
  # Initialize accumulators
  total_clinical <- 0
  total_severe <- 0
  total_deaths <- 0
  total_dalys <- 0
  total_treatment_cost <- 0
  total_intervention_cost <- 0
  
  results <- data.frame()
  
  # Loop over geographic settings
  for(geo in c("Urban", "Rural")) {
    geo_pop <- cohort_size * ifelse(geo == "Urban", 0.30, 0.70)
    gp <- geo_params[[geo]]
    
    # Calculate effective transmission
    effective_eir <- base_eir * gp$eir_multiplier
    monthly_bites <- effective_eir / 12
    monthly_infection_prob <- 1 - exp(-monthly_bites * 0.5)
    
    # Apply ITN effect
    itn_effect <- 1 - (itn_efficacy * gp$itn_coverage)
    monthly_infection_prob <- monthly_infection_prob * itn_effect
    
    # Apply strategy-specific effects
    intervention_cost <- 0
    
    if(intervention == "smc") {
      smc_effect <- 1 - (smc_efficacy * gp$smc_coverage)
      monthly_infection_prob <- monthly_infection_prob * smc_effect
      intervention_cost <- geo_pop * cost_smc_per_child_per_year * time_horizon_years
      
    } else if(intervention == "vaccine") {
      vaccine_effect <- 1 - (vaccine_ve_infection * gp$vaccine_coverage)
      monthly_infection_prob <- monthly_infection_prob * vaccine_effect
      intervention_cost <- geo_pop * cost_vaccine_full * gp$vaccine_coverage
      
    } else if(intervention == "combined") {
      smc_effect <- 1 - (smc_efficacy * gp$smc_coverage)
      vaccine_effect <- 1 - (vaccine_ve_infection * gp$vaccine_coverage)
      monthly_infection_prob <- monthly_infection_prob * smc_effect * vaccine_effect
      
      smc_cost <- geo_pop * cost_smc_per_child_per_year * time_horizon_years
      vaccine_cost <- geo_pop * cost_vaccine_full * gp$vaccine_coverage
      delivery_multiplier <- ifelse(geo == "Rural", 1.5, 1)
      intervention_cost <- (smc_cost + vaccine_cost) * delivery_multiplier
    }
    
    total_intervention_cost <- total_intervention_cost + intervention_cost
    
    # Loop over age groups
    for(a in 1:length(age_groups)) {
      age <- age_groups[a]
      age_pop <- geo_pop * age_weights[a]
      
      # Age-specific parameters
      if(age == "0-6m") {
        clinical_risk <- 0.25
        severe_risk <- 0.08
        cfr <- 0.18 * gp$cfr_multiplier * (1 + gp$access_delay_days/10)
      } else if(age == "6-24m") {
        clinical_risk <- 0.20
        severe_risk <- 0.06
        cfr <- 0.12 * gp$cfr_multiplier * (1 + gp$access_delay_days/10)
      } else if(age == "2-5y") {
        clinical_risk <- 0.10
        severe_risk <- 0.02
        cfr <- 0.06 * gp$cfr_multiplier * (1 + gp$access_delay_days/10)
      } else {
        clinical_risk <- 0.04
        severe_risk <- 0.005
        cfr <- 0.03 * gp$cfr_multiplier * (1 + gp$access_delay_days/10)
      }
      
      # Apply vaccine effect on severe disease
      if(intervention %in% c("vaccine", "combined")) {
        severe_risk <- severe_risk * (1 - vaccine_ve_severe * gp$vaccine_coverage)
      }
      
      # Initialize susceptible population
      susceptible <- age_pop
      clinical_cases <- 0
      severe_cases <- 0
      deaths <- 0
      discounted_treatment_cost <- 0
      discounted_dalys <- 0
      
      # Monthly simulation
      for(month in 1:(time_horizon_years * 12)) {
        discount_factor <- 1 / (1 + discount_rate)^(month/12)
        
        new_infections <- susceptible * monthly_infection_prob
        new_clinical <- new_infections * clinical_risk
        new_severe <- new_clinical * severe_risk
        new_deaths <- new_severe * cfr
        
        clinical_cases <- clinical_cases + new_clinical
        severe_cases <- severe_cases + new_severe
        deaths <- deaths + new_deaths
        
        # Treatment costs (discounted)
        treatment_cost <- (new_clinical * (cost_outpatient + cost_act) +
                          new_severe * (cost_hospital + cost_act)) * discount_factor
        discounted_treatment_cost <- discounted_treatment_cost + treatment_cost
        
        # DALYs (discounted)
        yll <- new_deaths * life_expectancy * discount_factor
        yld <- (new_clinical * dw_clinical * duration_clinical_years +
                new_severe * dw_severe * duration_severe_years) * discount_factor
        discounted_dalys <- discounted_dalys + yll + yld
        
        # Update susceptible population
        susceptible <- susceptible - new_infections
        if(susceptible < age_pop * 0.1) susceptible <- age_pop * 0.1
      }
      
      # Accumulate totals
      total_clinical <- total_clinical + clinical_cases
      total_severe <- total_severe + severe_cases
      total_deaths <- total_deaths + deaths
      total_dalys <- total_dalys + discounted_dalys
      total_treatment_cost <- total_treatment_cost + discounted_treatment_cost
      
      # Store results
      results <- rbind(results, data.frame(
        geography = geo,
        age_group = age,
        clinical_cases = clinical_cases,
        severe_cases = severe_cases,
        deaths = deaths,
        dalys_discounted = discounted_dalys,
        treatment_cost_discounted = discounted_treatment_cost
      ))
    }
  }
  
  total_costs <- total_treatment_cost + total_intervention_cost
  
  return(list(
    results = results,
    total_clinical = total_clinical,
    total_severe = total_severe,
    total_deaths = total_deaths,
    total_dalys = total_dalys,
    total_costs = total_costs,
    intervention_cost_discounted = total_intervention_cost,
    treatment_cost_discounted = total_treatment_cost
  ))
}

Model Results

Part 3: Run All Strategies

# ===================================================================
# STEP 9: EXECUTE MODEL FOR ALL FOUR INTERVENTION STRATEGIES
# ===================================================================

strategies <- c("baseline", "smc", "vaccine", "combined")
strategy_names <- c("Baseline (ITNs)", "SMC + ITNs", "Vaccine + ITNs", "Combined")

results_list <- list()

for(i in 1:length(strategies)) {
  cat(sprintf("Running %s...\n", strategy_names[i]))
  
  result <- run_stable_model(intervention = strategies[i], 
                            time_horizon_years = 10,
                            cohort_size = 10000)
  
  results_list[[i]] <- result
  
  cat(sprintf("  Clinical cases: %.0f\n", result$total_clinical))
  cat(sprintf("  Severe cases: %.0f\n", result$total_severe))
  cat(sprintf("  Deaths: %.0f\n", result$total_deaths))
  cat(sprintf("  DALYs (discounted): %.0f\n", result$total_dalys))
  cat(sprintf("  Total costs (discounted): $%.0f\n", result$total_costs))
  cat("\n")
}
## Running Baseline (ITNs)...
##   Clinical cases: 5791
##   Severe cases: 207
##   Deaths: 58
##   DALYs (discounted): 3292
##   Total costs (discounted): $75813
## 
## Running SMC + ITNs...
##   Clinical cases: 3715
##   Severe cases: 133
##   Deaths: 37
##   DALYs (discounted): 2131
##   Total costs (discounted): $648973
## 
## Running Vaccine + ITNs...
##   Clinical cases: 5110
##   Severe cases: 127
##   Deaths: 36
##   DALYs (discounted): 2069
##   Total costs (discounted): $183113
## 
## Running Combined...
##   Clinical cases: 3306
##   Severe cases: 82
##   Deaths: 23
##   DALYs (discounted): 1349
##   Total costs (discounted): $1008756

Part 4: Cost-Effectiveness Results (Discounted)

# ===================================================================
# STEP 10: CALCULATE COST-EFFECTIVENESS METRICS
# ===================================================================
# NOTE: Costs and DALYs are discounted at 3% per annum
# Cases and deaths are undiscounted (reported as is)

# Create results table
ce_table <- data.frame(
  Strategy = strategy_names,
  Clinical_Cases = sapply(results_list, function(x) x$total_clinical),
  Severe_Cases = sapply(results_list, function(x) x$total_severe),
  Deaths = sapply(results_list, function(x) x$total_deaths),
  DALYs = sapply(results_list, function(x) x$total_dalys),
  Costs = sapply(results_list, function(x) x$total_costs)
)

# Calculate incremental outcomes
ce_table$DALYs_Averted <- ce_table$DALYs[1] - ce_table$DALYs
ce_table$Inc_Cost <- ce_table$Costs - ce_table$Costs[1]
ce_table$ICER <- ce_table$Inc_Cost / ce_table$DALYs_Averted
ce_table$ICER[ce_table$DALYs_Averted <= 0] <- NA

# Format for display
display_table <- ce_table %>%
  mutate(
    Clinical_Cases = format_number(Clinical_Cases),
    Severe_Cases = format_number(Severe_Cases),
    Deaths = format_number(Deaths),
    DALYs = format_number(DALYs),
    Costs = paste0("$", format_number(Costs)),
    DALYs_Averted = format_number(DALYs_Averted),
    ICER = ifelse(is.na(ICER), "Dominated", paste0("$", format_number(ICER)))
  ) %>%
  select(Strategy, Clinical_Cases, Severe_Cases, Deaths, DALYs, Costs, DALYs_Averted, ICER)

kable(display_table, caption = "Cost-Effectiveness Results (10-year horizon, 10,000 children)",
      format = "html") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed")) %>%
  row_spec(0, bold = TRUE)
Cost-Effectiveness Results (10-year horizon, 10,000 children)
Strategy Clinical_Cases Severe_Cases Deaths DALYs Costs DALYs_Averted ICER
Baseline (ITNs) 5,791 207 58 3,292 $ 75,813 0 Dominated
SMC + ITNs 3,715 133 37 2,131 $ 648,973 1,161 $494
Vaccine + ITNs 5,110 127 36 2,069 $ 183,113 1,224 $ 88
Combined 3,306 82 23 1,349 $1,008,756 1,943 $480
# WTP threshold interpretation
cat("\n### Interpretation (WTP threshold: $800 per DALY averted):\n\n")
## 
## ### Interpretation (WTP threshold: $800 per DALY averted):
for(i in 2:nrow(ce_table)) {
  if(!is.na(ce_table$ICER[i])) {
    if(ce_table$ICER[i] < 800) {
      cat(sprintf("- **%s**: ✓ Cost-effective (ICER = $%s)\n", 
                  ce_table$Strategy[i], format_number(ce_table$ICER[i])))
    } else {
      cat(sprintf("- **%s**: ✗ Not cost-effective (ICER = $%s)\n", 
                  ce_table$Strategy[i], format_number(ce_table$ICER[i])))
    }
  }
}
## - **SMC + ITNs**: ✓ Cost-effective (ICER = $494)
## - **Vaccine + ITNs**: ✓ Cost-effective (ICER = $88)
## - **Combined**: ✓ Cost-effective (ICER = $480)

Part 5: Geographic Subgroup Analysis

# ===================================================================
# GEOGRAPHIC SUBGROUP ANALYSIS
# ===================================================================

# Aggregate results by geography
geo_summary <- data.frame()

for(i in 1:length(strategies)) {
  geo_temp <- results_list[[i]]$results %>%
    group_by(geography) %>%
    summarise(
      Clinical_Cases = sum(clinical_cases),
      Severe_Cases = sum(severe_cases),
      Deaths = sum(deaths),
      DALYs_Discounted = sum(dalys_discounted),
      Treatment_Costs_Discounted = sum(treatment_cost_discounted),
      .groups = 'drop'
    ) %>%
    mutate(Strategy = strategy_names[i])
  
  geo_summary <- rbind(geo_summary, geo_temp)
}

# Display geographic results
for(geo in c("Urban", "Rural")) {
  cat(sprintf("\n========================================\n"))
  cat(sprintf("GEOGRAPHIC SETTING: %s\n", toupper(geo)))
  cat(sprintf("========================================\n\n"))
  
  # Filter for this geography
  geo_subset <- geo_summary[geo_summary$geography == geo, ]
  
  # Extract values safely - convert to numeric
  base_idx <- which(geo_subset$Strategy == strategy_names[1])
  base_dalys <- as.numeric(geo_subset$DALYs_Discounted[base_idx])
  base_cost <- as.numeric(geo_subset$Treatment_Costs_Discounted[base_idx])
  
  # Clinical outcomes table
  cat("Clinical Outcomes (Discounted):\n")
  cat("--------------------------------\n")
  for(i in 1:nrow(geo_subset)) {
    cat(sprintf("- %s: Clinical cases = %s, Deaths = %s, DALYs = %s\n",
                geo_subset$Strategy[i],
                format_number(geo_subset$Clinical_Cases[i]),
                format_number(geo_subset$Deaths[i]),
                format_number(geo_subset$DALYs_Discounted[i])))
  }
  
  cat("\nCost-Effectiveness:\n")
  cat("-------------------\n")
  
  # Calculate ICERs for each strategy
  for(i in 2:length(strategies)) {
    int_idx <- which(geo_subset$Strategy == strategy_names[i])
    
    # Convert to numeric to avoid list issues
    int_dalys <- as.numeric(geo_subset$DALYs_Discounted[int_idx])
    int_cost <- as.numeric(geo_subset$Treatment_Costs_Discounted[int_idx])
    
    # Calculate intervention cost for this geography
    intervention_cost_total <- as.numeric(results_list[[i]]$intervention_cost_discounted)
    geo_intervention_cost <- intervention_cost_total * (ifelse(geo == "Urban", 0.3, 0.7))
    
    # Calculate incremental values
    dalys_averted <- base_dalys - int_dalys
    inc_cost <- (int_cost + geo_intervention_cost) - base_cost
    
    # Calculate ICER if positive DALYs averted
    if(dalys_averted > 0 && is.finite(dalys_averted) && !is.na(dalys_averted)) {
      icer <- inc_cost / dalys_averted
      cat(sprintf("- %s: DALYs averted = %s, ICER = $%s\n", 
                  strategy_names[i], 
                  format_number(dalys_averted), 
                  format_number(icer)))
    } else {
      cat(sprintf("- %s: Dominated or extended dominance\n", strategy_names[i]))
    }
  }
  
  # Determine best strategy for this geography
  cat("\nMost Cost-Effective Strategy:\n")
  cat("------------------------------\n")
  
  # Calculate ICERs for all strategies (excluding baseline)
  icer_values <- c()
  strategy_labels <- c()
  
  for(i in 2:length(strategies)) {
    int_idx <- which(geo_subset$Strategy == strategy_names[i])
    int_dalys <- as.numeric(geo_subset$DALYs_Discounted[int_idx])
    int_cost <- as.numeric(geo_subset$Treatment_Costs_Discounted[int_idx])
    intervention_cost_total <- as.numeric(results_list[[i]]$intervention_cost_discounted)
    geo_intervention_cost <- intervention_cost_total * (ifelse(geo == "Urban", 0.3, 0.7))
    
    dalys_averted <- base_dalys - int_dalys
    inc_cost <- (int_cost + geo_intervention_cost) - base_cost
    
    if(dalys_averted > 0 && is.finite(dalys_averted) && !is.na(dalys_averted)) {
      icer <- inc_cost / dalys_averted
      icer_values <- c(icer_values, icer)
      strategy_labels <- c(strategy_labels, strategy_names[i])
    }
  }
  
  if(length(icer_values) > 0) {
    best_idx <- which.min(icer_values)
    cat(sprintf("✓ %s (ICER: $%s per DALY averted)\n", 
                strategy_labels[best_idx], 
                format_number(icer_values[best_idx])))
  }
  
  cat("\n")
}
## 
## ========================================
## GEOGRAPHIC SETTING: URBAN
## ========================================
## 
## Clinical Outcomes (Discounted):
## --------------------------------
## - Baseline (ITNs): Clinical cases = 816, Deaths = 4, DALYs = 231
## - SMC + ITNs: Clinical cases = 507, Deaths = 2, DALYs = 146
## - Vaccine + ITNs: Clinical cases = 687, Deaths = 2, DALYs = 107
## - Combined: Clinical cases = 439, Deaths = 1, DALYs = 69
## 
## Cost-Effectiveness:
## -------------------
## - SMC + ITNs: DALYs averted = 85, ICER = $2,064
## - Vaccine + ITNs: DALYs averted = 124, ICER = $272
## - Combined: DALYs averted = 162, ICER = $1,760
## 
## Most Cost-Effective Strategy:
## ------------------------------
## ✓ Vaccine + ITNs (ICER: $272 per DALY averted)
## 
## 
## ========================================
## GEOGRAPHIC SETTING: RURAL
## ========================================
## 
## Clinical Outcomes (Discounted):
## --------------------------------
## - Baseline (ITNs): Clinical cases = 4,975, Deaths = 54, DALYs = 3,061
## - SMC + ITNs: Clinical cases = 3,208, Deaths = 35, DALYs = 1,985
## - Vaccine + ITNs: Clinical cases = 4,423, Deaths = 34, DALYs = 1,962
## - Combined: Clinical cases = 2,867, Deaths = 22, DALYs = 1,280
## 
## Cost-Effectiveness:
## -------------------
## - SMC + ITNs: DALYs averted = 1,076, ICER = $369
## - Vaccine + ITNs: DALYs averted = 1,099, ICER = $67
## - Combined: DALYs averted = 1,781, ICER = $364
## 
## Most Cost-Effective Strategy:
## ------------------------------
## ✓ Vaccine + ITNs (ICER: $67 per DALY averted)
# ===================================================================
# ALTERNATIVE: Create a formatted table using kable
# ===================================================================

# Create summary tables for reporting
cat("\n\n========================================\n")
## 
## 
## ========================================
cat("GEOGRAPHIC SUMMARY TABLES\n")
## GEOGRAPHIC SUMMARY TABLES
cat("========================================\n\n")
## ========================================
# Urban summary table
urban_summary <- geo_summary[geo_summary$geography == "Urban", ] %>%
  mutate(
    Clinical_Cases = format_number(Clinical_Cases),
    Severe_Cases = format_number(Severe_Cases),
    Deaths = format_number(Deaths),
    DALYs = format_number(DALYs_Discounted),
    Costs = paste0("$", format_number(Treatment_Costs_Discounted))
  ) %>%
  select(Strategy, Clinical_Cases, Severe_Cases, Deaths, DALYs, Costs)

cat("URBAN SETTINGS:\n")
## URBAN SETTINGS:
print(urban_summary)
## # A tibble: 4 × 6
##   Strategy        Clinical_Cases Severe_Cases Deaths DALYs Costs  
##   <chr>           <chr>          <chr>        <chr>  <chr> <chr>  
## 1 Baseline (ITNs) 816            "29"         4      "231" $10,830
## 2 SMC + ITNs      507            "18"         2      "146" $ 6,833
## 3 Vaccine + ITNs  687            "13"         2      "107" $ 7,650
## 4 Combined        439            " 9"         1      " 69" $ 4,960
# Rural summary table
rural_summary <- geo_summary[geo_summary$geography == "Rural", ] %>%
  mutate(
    Clinical_Cases = format_number(Clinical_Cases),
    Severe_Cases = format_number(Severe_Cases),
    Deaths = format_number(Deaths),
    DALYs = format_number(DALYs_Discounted),
    Costs = paste0("$", format_number(Treatment_Costs_Discounted))
  ) %>%
  select(Strategy, Clinical_Cases, Severe_Cases, Deaths, DALYs, Costs)

cat("\nRURAL SETTINGS:\n")
## 
## RURAL SETTINGS:
print(rural_summary)
## # A tibble: 4 × 6
##   Strategy        Clinical_Cases Severe_Cases Deaths DALYs Costs  
##   <chr>           <chr>          <chr>        <chr>  <chr> <chr>  
## 1 Baseline (ITNs) 4,975          "178"        54     3,061 $64,983
## 2 SMC + ITNs      3,208          "115"        35     1,985 $42,140
## 3 Vaccine + ITNs  4,423          "114"        34     1,962 $51,963
## 4 Combined        2,867          " 74"        22     1,280 $33,895
# ===================================================================
# CALCULATE GEOGRAPHIC ICER MATRIX
# ===================================================================

cat("\n\n========================================\n")
## 
## 
## ========================================
cat("GEOGRAPHIC ICER MATRIX\n")
## GEOGRAPHIC ICER MATRIX
cat("========================================\n\n")
## ========================================
# Create empty data frame for geographic ICERs
geo_icer_matrix <- data.frame(
  Strategy = strategy_names[2:4],
  Urban_ICER = NA,
  Rural_ICER = NA,
  Urban_DALYs_Averted = NA,
  Rural_DALYs_Averted = NA
)

for(i in 2:length(strategies)) {
  # Urban calculations
  urban_base_dalys <- as.numeric(geo_summary[geo_summary$geography == "Urban" & 
                                              geo_summary$Strategy == strategy_names[1], "DALYs_Discounted"])
  urban_int_dalys <- as.numeric(geo_summary[geo_summary$geography == "Urban" & 
                                             geo_summary$Strategy == strategy_names[i], "DALYs_Discounted"])
  urban_base_cost <- as.numeric(geo_summary[geo_summary$geography == "Urban" & 
                                             geo_summary$Strategy == strategy_names[1], "Treatment_Costs_Discounted"])
  urban_int_cost <- as.numeric(geo_summary[geo_summary$geography == "Urban" & 
                                            geo_summary$Strategy == strategy_names[i], "Treatment_Costs_Discounted"])
  
  urban_intervention_cost <- as.numeric(results_list[[i]]$intervention_cost_discounted) * 0.3
  urban_dalys_averted <- urban_base_dalys - urban_int_dalys
  urban_inc_cost <- (urban_int_cost + urban_intervention_cost) - urban_base_cost
  
  if(urban_dalys_averted > 0 && is.finite(urban_dalys_averted)) {
    geo_icer_matrix$Urban_ICER[i-1] <- urban_inc_cost / urban_dalys_averted
    geo_icer_matrix$Urban_DALYs_Averted[i-1] <- urban_dalys_averted
  }
  
  # Rural calculations
  rural_base_dalys <- as.numeric(geo_summary[geo_summary$geography == "Rural" & 
                                              geo_summary$Strategy == strategy_names[1], "DALYs_Discounted"])
  rural_int_dalys <- as.numeric(geo_summary[geo_summary$geography == "Rural" & 
                                             geo_summary$Strategy == strategy_names[i], "DALYs_Discounted"])
  rural_base_cost <- as.numeric(geo_summary[geo_summary$geography == "Rural" & 
                                             geo_summary$Strategy == strategy_names[1], "Treatment_Costs_Discounted"])
  rural_int_cost <- as.numeric(geo_summary[geo_summary$geography == "Rural" & 
                                            geo_summary$Strategy == strategy_names[i], "Treatment_Costs_Discounted"])
  
  rural_intervention_cost <- as.numeric(results_list[[i]]$intervention_cost_discounted) * 0.7
  rural_dalys_averted <- rural_base_dalys - rural_int_dalys
  rural_inc_cost <- (rural_int_cost + rural_intervention_cost) - rural_base_cost
  
  if(rural_dalys_averted > 0 && is.finite(rural_dalys_averted)) {
    geo_icer_matrix$Rural_ICER[i-1] <- rural_inc_cost / rural_dalys_averted
    geo_icer_matrix$Rural_DALYs_Averted[i-1] <- rural_dalys_averted
  }
}

# Display ICER matrix
geo_icer_matrix_display <- geo_icer_matrix %>%
  mutate(
    Urban_ICER = ifelse(is.na(Urban_ICER), "Dominated", paste0("$", format_number(Urban_ICER))),
    Rural_ICER = ifelse(is.na(Rural_ICER), "Dominated", paste0("$", format_number(Rural_ICER))),
    Urban_DALYs_Averted = format_number(Urban_DALYs_Averted),
    Rural_DALYs_Averted = format_number(Rural_DALYs_Averted)
  )

print(geo_icer_matrix_display)
##         Strategy Urban_ICER Rural_ICER Urban_DALYs_Averted Rural_DALYs_Averted
## 1     SMC + ITNs     $2,064       $369                  85               1,076
## 2 Vaccine + ITNs     $  272       $ 67                 124               1,099
## 3       Combined     $1,760       $364                 162               1,781
# ===================================================================
# GEOGRAPHIC EQUITY ANALYSIS
# ===================================================================

cat("\n\n========================================\n")
## 
## 
## ========================================
cat("GEOGRAPHIC EQUITY ANALYSIS\n")
## GEOGRAPHIC EQUITY ANALYSIS
cat("========================================\n\n")
## ========================================
# Calculate DALYs averted per capita by geography
combined_idx <- which(strategy_names == "Combined")

# Urban population: 30% of 10,000 = 3,000
# Rural population: 70% of 10,000 = 7,000

urban_pop <- 3000
rural_pop <- 7000

urban_dalys_averted <- geo_icer_matrix$Urban_DALYs_Averted[3]  # Combined strategy
rural_dalys_averted <- geo_icer_matrix$Rural_DALYs_Averted[3]

urban_dalys_per_capita <- urban_dalys_averted / urban_pop * 1000
rural_dalys_per_capita <- rural_dalys_averted / rural_pop * 1000

cat("Combined Strategy Equity Analysis:\n")
## Combined Strategy Equity Analysis:
cat("----------------------------------\n")
## ----------------------------------
cat(sprintf("Urban population: %s\n", format_number(urban_pop)))
## Urban population: 3,000
cat(sprintf("Rural population: %s\n", format_number(rural_pop)))
## Rural population: 7,000
cat(sprintf("\nUrban DALYs averted: %s\n", format_number(urban_dalys_averted)))
## 
## Urban DALYs averted: 162
cat(sprintf("Rural DALYs averted: %s\n", format_number(rural_dalys_averted)))
## Rural DALYs averted: 1,781
cat(sprintf("\nUrban DALYs averted per 1000: %.1f\n", urban_dalys_per_capita))
## 
## Urban DALYs averted per 1000: 54.0
cat(sprintf("Rural DALYs averted per 1000: %.1f\n", rural_dalys_per_capita))
## Rural DALYs averted per 1000: 254.5
equity_ratio <- rural_dalys_per_capita / urban_dalys_per_capita
cat(sprintf("\nEquity Ratio (Rural/Urban): %.2f\n", equity_ratio))
## 
## Equity Ratio (Rural/Urban): 4.71
if(equity_ratio < 0.8) {
  cat("\n⚠️  STRONG PRO-URBAN BIAS DETECTED\n")
  cat("Rural populations benefit significantly less from interventions\n")
  cat("\nRecommendations to improve equity:\n")
  cat("  1. Increase rural coverage targets by 30-50%\n")
  cat("  2. Subsidize transport costs for rural families\n")
  cat("  3. Implement mobile vaccination campaigns in remote areas\n")
  cat("  4. Train community health workers for SMC delivery\n")
} else if(equity_ratio < 1.2) {
  cat("\n✓ EQUITABLE DISTRIBUTION\n")
  cat("Benefits are relatively balanced across geographic settings\n")
} else {
  cat("\n✓ PRO-RURAL DISTRIBUTION\n")
  cat("Rural populations benefit more, which is desirable for equity\n")
}
## 
## ✓ PRO-RURAL DISTRIBUTION
## Rural populations benefit more, which is desirable for equity
# ===================================================================
# RECOMMENDATIONS BY GEOGRAPHY
# ===================================================================

cat("\n\n========================================\n")
## 
## 
## ========================================
cat("RECOMMENDATIONS BY GEOGRAPHY\n")
## RECOMMENDATIONS BY GEOGRAPHY
cat("========================================\n\n")
## ========================================
# Urban recommendations
cat("URBAN AREAS:\n")
## URBAN AREAS:
cat("------------\n")
## ------------
urban_best_idx <- which.min(geo_icer_matrix$Urban_ICER[!is.na(geo_icer_matrix$Urban_ICER)])
urban_best_strategy <- geo_icer_matrix$Strategy[urban_best_idx]
urban_best_icer <- min(geo_icer_matrix$Urban_ICER[!is.na(geo_icer_matrix$Urban_ICER)])

cat(sprintf("Most cost-effective: %s (ICER: $%s per DALY)\n", 
            urban_best_strategy, format_number(urban_best_icer)))
## Most cost-effective: Vaccine + ITNs (ICER: $272 per DALY)
cat("\nRecommendations for URBAN areas:\n")
## 
## Recommendations for URBAN areas:
cat("  - Focus on Vaccine + ITNs (excellent value for money)\n")
##   - Focus on Vaccine + ITNs (excellent value for money)
cat("  - Maintain high ITN coverage (currently 70%)\n")
##   - Maintain high ITN coverage (currently 70%)
cat("  - Target vaccination in 6-24 month age group\n")
##   - Target vaccination in 6-24 month age group
cat("  - Strengthen case management at existing facilities\n")
##   - Strengthen case management at existing facilities
# Rural recommendations
cat("\nRURAL AREAS:\n")
## 
## RURAL AREAS:
cat("------------\n")
## ------------
rural_best_idx <- which.min(geo_icer_matrix$Rural_ICER[!is.na(geo_icer_matrix$Rural_ICER)])
rural_best_strategy <- geo_icer_matrix$Strategy[rural_best_idx]
rural_best_icer <- min(geo_icer_matrix$Rural_ICER[!is.na(geo_icer_matrix$Rural_ICER)])

cat(sprintf("Most cost-effective: %s (ICER: $%s per DALY)\n", 
            rural_best_strategy, format_number(rural_best_icer)))
## Most cost-effective: Vaccine + ITNs (ICER: $67 per DALY)
cat("\nRecommendations for RURAL areas:\n")
## 
## Recommendations for RURAL areas:
cat("  - Prioritize Vaccine + ITNs (most cost-effective)\n")
##   - Prioritize Vaccine + ITNs (most cost-effective)
cat("  - Increase vaccine coverage from 40% to 65%\n")
##   - Increase vaccine coverage from 40% to 65%
cat("  - Add SMC during rainy season for 2-5 year olds\n")
##   - Add SMC during rainy season for 2-5 year olds
cat("  - Deploy mobile health teams for outreach\n")
##   - Deploy mobile health teams for outreach
cat("  - Train community health workers for vaccine delivery\n")
##   - Train community health workers for vaccine delivery
cat("\n\n========================================\n")
## 
## 
## ========================================
cat("GEOGRAPHIC ANALYSIS COMPLETE\n")
## GEOGRAPHIC ANALYSIS COMPLETE
cat("========================================\n")
## ========================================

PROBABILISTIC SENSITIVITY ANALYSIS (PSA)

# Load additional packages for PSA
library(mvtnorm)
library(ellipse)
library(scales)

set.seed(2026)

PSA Function

run_psa_analysis <- function(n_simulations = 10000, 
                            time_horizon_years = 10,
                            cohort_size = 10000) {
  
  cat("\n========================================\n")
  cat("PROBABILISTIC SENSITIVITY ANALYSIS (PSA)\n")
  cat("========================================\n")
  cat(sprintf("Number of simulations: %d\n", n_simulations))
  cat("This may take several minutes...\n\n")
  
  # Initialize results data frame
  psa_results <- data.frame(
    sim_id = 1:n_simulations,
    
    # Baseline outcomes
    baseline_cases = NA,
    baseline_deaths = NA,
    baseline_dalys = NA,
    baseline_costs = NA,
    
    # SMC outcomes
    smc_cases = NA,
    smc_deaths = NA,
    smc_dalys = NA,
    smc_costs = NA,
    
    # Vaccine outcomes
    vaccine_cases = NA,
    vaccine_deaths = NA,
    vaccine_dalys = NA,
    vaccine_costs = NA,
    
    # Combined outcomes
    combined_cases = NA,
    combined_deaths = NA,
    combined_dalys = NA,
    combined_costs = NA,
    
    # Incremental outcomes
    inc_effect_smc = NA,
    inc_cost_smc = NA,
    inc_effect_vaccine = NA,
    inc_cost_vaccine = NA,
    inc_effect_combined = NA,
    inc_cost_combined = NA,
    
    # ICERs
    icer_smc = NA,
    icer_vaccine = NA,
    icer_combined = NA
  )
  
  # Progress bar
  pb <- txtProgressBar(min = 0, max = n_simulations, style = 3)
  
  for(sim in 1:n_simulations) {
    
    # Sample parameters from uncertainty distributions
    eir_sample <- rlnorm(1, meanlog = log(25), sdlog = 0.25)
    ve_infection_sample <- rbeta(1, shape1 = 35, shape2 = 82)
    ve_severe_sample <- rbeta(1, shape1 = 75, shape2 = 32)
    smc_efficacy_sample <- rbeta(1, shape1 = 90, shape2 = 16)
    itn_efficacy_sample <- rbeta(1, shape1 = 50, shape2 = 61)
    
    # Coverage samples
    itn_cov_urban <- rbeta(1, shape1 = 72, shape2 = 31)
    itn_cov_rural <- rbeta(1, shape1 = 47, shape2 = 57)
    vaccine_cov_urban <- rbeta(1, shape1 = 67, shape2 = 36)
    vaccine_cov_rural <- rbeta(1, shape1 = 42, shape2 = 63)
    smc_cov_urban <- rbeta(1, shape1 = 57, shape2 = 46)
    smc_cov_rural <- rbeta(1, shape1 = 47, shape2 = 57)
    
    # Clinical parameters
    clinical_risk_u5 <- rbeta(1, shape1 = 22, shape2 = 88)
    severe_risk_u5 <- rbeta(1, shape1 = 7, shape2 = 110)
    cfr_sample <- rbeta(1, shape1 = 14, shape2 = 103)
    
    # Costs
    cost_vaccine_sample <- rgamma(1, shape = 12, rate = 0.46)
    cost_smc_sample <- rgamma(1, shape = 10, rate = 1.67)
    cost_act_sample <- rgamma(1, shape = 12, rate = 8.0)
    cost_outpatient_sample <- rgamma(1, shape = 10, rate = 1.25)
    cost_hospital_sample <- rgamma(1, shape = 15, rate = 0.10)
    
    # DALY weights
    dw_clinical_sample <- rbeta(1, shape1 = 6, shape2 = 994)
    dw_severe_sample <- rbeta(1, shape1 = 140, shape2 = 920)
    
    # Geographic weights
    urban_pop <- cohort_size * 0.30
    rural_pop <- cohort_size * 0.70
    
    # Run for each strategy (simplified for PSA speed)
    for(strategy in c("baseline", "smc", "vaccine", "combined")) {
      
      total_cases <- 0
      total_deaths <- 0
      total_dalys <- 0
      total_costs <- 0
      
      for(geo in c("Urban", "Rural")) {
        
        if(geo == "Urban") {
          geo_pop <- urban_pop
          eir_mult <- 0.4
          itn_cov <- itn_cov_urban
          vaccine_cov <- vaccine_cov_urban
          smc_cov <- smc_cov_urban
          cfr_mult <- 1.0
        } else {
          geo_pop <- rural_pop
          eir_mult <- 2.0
          itn_cov <- itn_cov_rural
          vaccine_cov <- vaccine_cov_rural
          smc_cov <- smc_cov_rural
          cfr_mult <- 1.6
        }
        
        # Calculate transmission
        effective_eir <- eir_sample * eir_mult
        monthly_bites <- effective_eir / 12
        monthly_infection_prob <- 1 - exp(-monthly_bites * 0.5)
        
        # ITN effect
        itn_effect <- 1 - (itn_efficacy_sample * itn_cov)
        monthly_infection_prob <- monthly_infection_prob * itn_effect
        
        # Strategy-specific effects
        if(strategy == "smc") {
          smc_effect <- 1 - (smc_efficacy_sample * smc_cov)
          monthly_infection_prob <- monthly_infection_prob * smc_effect
          intervention_cost <- geo_pop * cost_smc_sample * time_horizon_years
          severe_risk_adj <- severe_risk_u5
          
        } else if(strategy == "vaccine") {
          vaccine_effect <- 1 - (ve_infection_sample * vaccine_cov)
          monthly_infection_prob <- monthly_infection_prob * vaccine_effect
          intervention_cost <- geo_pop * cost_vaccine_sample * vaccine_cov
          severe_risk_adj <- severe_risk_u5 * (1 - ve_severe_sample * vaccine_cov)
          
        } else if(strategy == "combined") {
          smc_effect <- 1 - (smc_efficacy_sample * smc_cov)
          vaccine_effect <- 1 - (ve_infection_sample * vaccine_cov)
          monthly_infection_prob <- monthly_infection_prob * smc_effect * vaccine_effect
          
          smc_cost <- geo_pop * cost_smc_sample * time_horizon_years
          vaccine_cost <- geo_pop * cost_vaccine_sample * vaccine_cov
          delivery_multiplier <- ifelse(geo == "Rural", 1.5, 1)
          intervention_cost <- (smc_cost + vaccine_cost) * delivery_multiplier
          severe_risk_adj <- severe_risk_u5 * (1 - ve_severe_sample * vaccine_cov)
          
        } else {
          intervention_cost <- 0
          severe_risk_adj <- severe_risk_u5
        }
        
        # Adjust CFR
        cfr_adj <- cfr_sample * cfr_mult
        
        # Run simulation
        susceptible <- geo_pop
        geo_cases <- 0
        geo_deaths <- 0
        geo_treatment_cost <- 0
        
        for(month in 1:(time_horizon_years * 12)) {
          discount_factor <- 1 / (1 + 0.03)^(month/12)
          
          new_infections <- susceptible * monthly_infection_prob
          new_clinical <- new_infections * clinical_risk_u5
          new_severe <- new_clinical * severe_risk_adj
          new_deaths <- new_severe * cfr_adj
          
          geo_cases <- geo_cases + new_clinical
          geo_deaths <- geo_deaths + new_deaths
          
          treatment_cost <- (new_clinical * (cost_outpatient_sample + cost_act_sample) +
                            new_severe * (cost_hospital_sample + cost_act_sample)) * discount_factor
          geo_treatment_cost <- geo_treatment_cost + treatment_cost
          
          susceptible <- susceptible - new_infections
          if(susceptible < geo_pop * 0.1) susceptible <- geo_pop * 0.1
        }
        
        # Calculate DALYs
        yll <- geo_deaths * life_expectancy
        yld <- geo_cases * dw_clinical_sample * 0.038 + 
               geo_cases * severe_risk_adj * dw_severe_sample * 0.058
        geo_dalys <- (yll + yld) * 0.85
        
        total_cases <- total_cases + geo_cases
        total_deaths <- total_deaths + geo_deaths
        total_dalys <- total_dalys + geo_dalys
        total_costs <- total_costs + geo_treatment_cost + intervention_cost
      }
      
      # Store results
      if(strategy == "baseline") {
        psa_results$baseline_cases[sim] <- total_cases
        psa_results$baseline_deaths[sim] <- total_deaths
        psa_results$baseline_dalys[sim] <- total_dalys
        psa_results$baseline_costs[sim] <- total_costs
      } else if(strategy == "smc") {
        psa_results$smc_cases[sim] <- total_cases
        psa_results$smc_deaths[sim] <- total_deaths
        psa_results$smc_dalys[sim] <- total_dalys
        psa_results$smc_costs[sim] <- total_costs
      } else if(strategy == "vaccine") {
        psa_results$vaccine_cases[sim] <- total_cases
        psa_results$vaccine_deaths[sim] <- total_deaths
        psa_results$vaccine_dalys[sim] <- total_dalys
        psa_results$vaccine_costs[sim] <- total_costs
      } else {
        psa_results$combined_cases[sim] <- total_cases
        psa_results$combined_deaths[sim] <- total_deaths
        psa_results$combined_dalys[sim] <- total_dalys
        psa_results$combined_costs[sim] <- total_costs
      }
    }
    
    # Calculate incremental outcomes
    psa_results$inc_effect_smc[sim] <- psa_results$baseline_dalys[sim] - psa_results$smc_dalys[sim]
    psa_results$inc_cost_smc[sim] <- psa_results$smc_costs[sim] - psa_results$baseline_costs[sim]
    psa_results$inc_effect_vaccine[sim] <- psa_results$baseline_dalys[sim] - psa_results$vaccine_dalys[sim]
    psa_results$inc_cost_vaccine[sim] <- psa_results$vaccine_costs[sim] - psa_results$baseline_costs[sim]
    psa_results$inc_effect_combined[sim] <- psa_results$baseline_dalys[sim] - psa_results$combined_dalys[sim]
    psa_results$inc_cost_combined[sim] <- psa_results$combined_costs[sim] - psa_results$baseline_costs[sim]
    
    # Calculate ICERs
    psa_results$icer_smc[sim] <- ifelse(psa_results$inc_effect_smc[sim] > 0,
                                        psa_results$inc_cost_smc[sim] / psa_results$inc_effect_smc[sim], NA)
    psa_results$icer_vaccine[sim] <- ifelse(psa_results$inc_effect_vaccine[sim] > 0,
                                            psa_results$inc_cost_vaccine[sim] / psa_results$inc_effect_vaccine[sim], NA)
    psa_results$icer_combined[sim] <- ifelse(psa_results$inc_effect_combined[sim] > 0,
                                             psa_results$inc_cost_combined[sim] / psa_results$inc_effect_combined[sim], NA)
    
    setTxtProgressBar(pb, sim)
  }
  
  close(pb)
  
  # Calculate summary statistics
  psa_summary <- data.frame(
    Strategy = c("SMC", "Vaccine", "Combined"),
    ICER_Mean = c(mean(psa_results$icer_smc, na.rm = TRUE),
                  mean(psa_results$icer_vaccine, na.rm = TRUE),
                  mean(psa_results$icer_combined, na.rm = TRUE)),
    ICER_Median = c(median(psa_results$icer_smc, na.rm = TRUE),
                    median(psa_results$icer_vaccine, na.rm = TRUE),
                    median(psa_results$icer_combined, na.rm = TRUE)),
    ICER_SD = c(sd(psa_results$icer_smc, na.rm = TRUE),
                sd(psa_results$icer_vaccine, na.rm = TRUE),
                sd(psa_results$icer_combined, na.rm = TRUE)),
    ICER_Lower95 = c(quantile(psa_results$icer_smc, 0.025, na.rm = TRUE),
                     quantile(psa_results$icer_vaccine, 0.025, na.rm = TRUE),
                     quantile(psa_results$icer_combined, 0.025, na.rm = TRUE)),
    ICER_Upper95 = c(quantile(psa_results$icer_smc, 0.975, na.rm = TRUE),
                     quantile(psa_results$icer_vaccine, 0.975, na.rm = TRUE),
                     quantile(psa_results$icer_combined, 0.975, na.rm = TRUE)),
    Prob_CE_100 = c(mean(psa_results$icer_smc <= 100, na.rm = TRUE),
                    mean(psa_results$icer_vaccine <= 100, na.rm = TRUE),
                    mean(psa_results$icer_combined <= 100, na.rm = TRUE)),
    Prob_CE_500 = c(mean(psa_results$icer_smc <= 500, na.rm = TRUE),
                    mean(psa_results$icer_vaccine <= 500, na.rm = TRUE),
                    mean(psa_results$icer_combined <= 500, na.rm = TRUE)),
    Prob_CE_800 = c(mean(psa_results$icer_smc <= 800, na.rm = TRUE),
                    mean(psa_results$icer_vaccine <= 800, na.rm = TRUE),
                    mean(psa_results$icer_combined <= 800, na.rm = TRUE))
  )
  
  return(list(results = psa_results, summary = psa_summary))
}

Run PSA

# Run PSA (10000 simulations)
psa_output <- run_psa_analysis(n_simulations = 10000, 
                               time_horizon_years = 10, 
                               cohort_size = 10000)
## 
## ========================================
## PROBABILISTIC SENSITIVITY ANALYSIS (PSA)
## ========================================
## Number of simulations: 10000
## This may take several minutes...
## 
##   |                                                                              |                                                                      |   0%  |                                                                              |                                                                      |   1%  |                                                                              |=                                                                     |   1%  |                                                                              |=                                                                     |   2%  |                                                                              |==                                                                    |   2%  |                                                                              |==                                                                    |   3%  |                                                                              |==                                                                    |   4%  |                                                                              |===                                                                   |   4%  |                                                                              |===                                                                   |   5%  |                                                                              |====                                                                  |   5%  |                                                                              |====                                                                  |   6%  |                                                                              |=====                                                                 |   6%  |                                                                              |=====                                                                 |   7%  |                                                                              |=====                                                                 |   8%  |                                                                              |======                                                                |   8%  |                                                                              |======                                                                |   9%  |                                                                              |=======                                                               |   9%  |                                                                              |=======                                                               |  10%  |                                                                              |=======                                                               |  11%  |                                                                              |========                                                              |  11%  |                                                                              |========                                                              |  12%  |                                                                              |=========                                                             |  12%  |                                                                              |=========                                                             |  13%  |                                                                              |=========                                                             |  14%  |                                                                              |==========                                                            |  14%  |                                                                              |==========                                                            |  15%  |                                                                              |===========                                                           |  15%  |                                                                              |===========                                                           |  16%  |                                                                              |============                                                          |  16%  |                                                                              |============                                                          |  17%  |                                                                              |============                                                          |  18%  |                                                                              |=============                                                         |  18%  |                                                                              |=============                                                         |  19%  |                                                                              |==============                                                        |  19%  |                                                                              |==============                                                        |  20%  |                                                                              |==============                                                        |  21%  |                                                                              |===============                                                       |  21%  |                                                                              |===============                                                       |  22%  |                                                                              |================                                                      |  22%  |                                                                              |================                                                      |  23%  |                                                                              |================                                                      |  24%  |                                                                              |=================                                                     |  24%  |                                                                              |=================                                                     |  25%  |                                                                              |==================                                                    |  25%  |                                                                              |==================                                                    |  26%  |                                                                              |===================                                                   |  26%  |                                                                              |===================                                                   |  27%  |                                                                              |===================                                                   |  28%  |                                                                              |====================                                                  |  28%  |                                                                              |====================                                                  |  29%  |                                                                              |=====================                                                 |  29%  |                                                                              |=====================                                                 |  30%  |                                                                              |=====================                                                 |  31%  |                                                                              |======================                                                |  31%  |                                                                              |======================                                                |  32%  |                                                                              |=======================                                               |  32%  |                                                                              |=======================                                               |  33%  |                                                                              |=======================                                               |  34%  |                                                                              |========================                                              |  34%  |                                                                              |========================                                              |  35%  |                                                                              |=========================                                             |  35%  |                                                                              |=========================                                             |  36%  |                                                                              |==========================                                            |  36%  |                                                                              |==========================                                            |  37%  |                                                                              |==========================                                            |  38%  |                                                                              |===========================                                           |  38%  |                                                                              |===========================                                           |  39%  |                                                                              |============================                                          |  39%  |                                                                              |============================                                          |  40%  |                                                                              |============================                                          |  41%  |                                                                              |=============================                                         |  41%  |                                                                              |=============================                                         |  42%  |                                                                              |==============================                                        |  42%  |                                                                              |==============================                                        |  43%  |                                                                              |==============================                                        |  44%  |                                                                              |===============================                                       |  44%  |                                                                              |===============================                                       |  45%  |                                                                              |================================                                      |  45%  |                                                                              |================================                                      |  46%  |                                                                              |=================================                                     |  46%  |                                                                              |=================================                                     |  47%  |                                                                              |=================================                                     |  48%  |                                                                              |==================================                                    |  48%  |                                                                              |==================================                                    |  49%  |                                                                              |===================================                                   |  49%  |                                                                              |===================================                                   |  50%  |                                                                              |===================================                                   |  51%  |                                                                              |====================================                                  |  51%  |                                                                              |====================================                                  |  52%  |                                                                              |=====================================                                 |  52%  |                                                                              |=====================================                                 |  53%  |                                                                              |=====================================                                 |  54%  |                                                                              |======================================                                |  54%  |                                                                              |======================================                                |  55%  |                                                                              |=======================================                               |  55%  |                                                                              |=======================================                               |  56%  |                                                                              |========================================                              |  56%  |                                                                              |========================================                              |  57%  |                                                                              |========================================                              |  58%  |                                                                              |=========================================                             |  58%  |                                                                              |=========================================                             |  59%  |                                                                              |==========================================                            |  59%  |                                                                              |==========================================                            |  60%  |                                                                              |==========================================                            |  61%  |                                                                              |===========================================                           |  61%  |                                                                              |===========================================                           |  62%  |                                                                              |============================================                          |  62%  |                                                                              |============================================                          |  63%  |                                                                              |============================================                          |  64%  |                                                                              |=============================================                         |  64%  |                                                                              |=============================================                         |  65%  |                                                                              |==============================================                        |  65%  |                                                                              |==============================================                        |  66%  |                                                                              |===============================================                       |  66%  |                                                                              |===============================================                       |  67%  |                                                                              |===============================================                       |  68%  |                                                                              |================================================                      |  68%  |                                                                              |================================================                      |  69%  |                                                                              |=================================================                     |  69%  |                                                                              |=================================================                     |  70%  |                                                                              |=================================================                     |  71%  |                                                                              |==================================================                    |  71%  |                                                                              |==================================================                    |  72%  |                                                                              |===================================================                   |  72%  |                                                                              |===================================================                   |  73%  |                                                                              |===================================================                   |  74%  |                                                                              |====================================================                  |  74%  |                                                                              |====================================================                  |  75%  |                                                                              |=====================================================                 |  75%  |                                                                              |=====================================================                 |  76%  |                                                                              |======================================================                |  76%  |                                                                              |======================================================                |  77%  |                                                                              |======================================================                |  78%  |                                                                              |=======================================================               |  78%  |                                                                              |=======================================================               |  79%  |                                                                              |========================================================              |  79%  |                                                                              |========================================================              |  80%  |                                                                              |========================================================              |  81%  |                                                                              |=========================================================             |  81%  |                                                                              |=========================================================             |  82%  |                                                                              |==========================================================            |  82%  |                                                                              |==========================================================            |  83%  |                                                                              |==========================================================            |  84%  |                                                                              |===========================================================           |  84%  |                                                                              |===========================================================           |  85%  |                                                                              |============================================================          |  85%  |                                                                              |============================================================          |  86%  |                                                                              |=============================================================         |  86%  |                                                                              |=============================================================         |  87%  |                                                                              |=============================================================         |  88%  |                                                                              |==============================================================        |  88%  |                                                                              |==============================================================        |  89%  |                                                                              |===============================================================       |  89%  |                                                                              |===============================================================       |  90%  |                                                                              |===============================================================       |  91%  |                                                                              |================================================================      |  91%  |                                                                              |================================================================      |  92%  |                                                                              |=================================================================     |  92%  |                                                                              |=================================================================     |  93%  |                                                                              |=================================================================     |  94%  |                                                                              |==================================================================    |  94%  |                                                                              |==================================================================    |  95%  |                                                                              |===================================================================   |  95%  |                                                                              |===================================================================   |  96%  |                                                                              |====================================================================  |  96%  |                                                                              |====================================================================  |  97%  |                                                                              |====================================================================  |  98%  |                                                                              |===================================================================== |  98%  |                                                                              |===================================================================== |  99%  |                                                                              |======================================================================|  99%  |                                                                              |======================================================================| 100%
psa_results <- psa_output$results
psa_summary <- psa_output$summary

PSA Summary Statistics

kable(psa_summary, caption = "PSA Summary Statistics (10000 simulations)",
      digits = 0, format = "html") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
PSA Summary Statistics (10000 simulations)
Strategy ICER_Mean ICER_Median ICER_SD ICER_Lower95 ICER_Upper95 Prob_CE_100 Prob_CE_500 Prob_CE_800
SMC 217 172 173 43 651 0 1 1
Vaccine 28 21 31 -4 109 1 1 1
Combined 212 171 158 50 614 0 1 1

PSA Visualizations

Cost-Effectiveness Planes

# Function to create CE plane
create_ce_plane <- function(psa_results, strategy_name) {
  
  if(strategy_name == "SMC") {
    data <- data.frame(
      effect = psa_results$inc_effect_smc,
      cost = psa_results$inc_cost_smc,
      icer = psa_results$icer_smc
    )
    color <- "#377EB8"
  } else if(strategy_name == "Vaccine") {
    data <- data.frame(
      effect = psa_results$inc_effect_vaccine,
      cost = psa_results$inc_cost_vaccine,
      icer = psa_results$icer_vaccine
    )
    color <- "#4DAF4A"
  } else {
    data <- data.frame(
      effect = psa_results$inc_effect_combined,
      cost = psa_results$inc_cost_combined,
      icer = psa_results$icer_combined
    )
    color <- "#E41A1C"
  }
  
  data <- data[!is.na(data$effect) & !is.na(data$cost) & data$effect > 0, ]
  
  # Calculate 95% confidence ellipse
  if(nrow(data) > 2) {
    ellipse_data <- ellipse(cov(data[, c("effect", "cost")]), 
                           centre = colMeans(data[, c("effect", "cost")]),
                           level = 0.95)
    ellipse_df <- as.data.frame(ellipse_data)
    colnames(ellipse_df) <- c("effect", "cost")
  } else {
    ellipse_df <- NULL
  }
  
  p <- ggplot(data, aes(x = effect, y = cost)) +
    geom_point(alpha = 0.3, size = 1.5, color = color) +
    geom_hline(yintercept = 0, linetype = "dashed", color = "gray50") +
    geom_vline(xintercept = 0, linetype = "dashed", color = "gray50") +
    geom_abline(intercept = 0, slope = 100, linetype = "dotted", color = "darkgreen") +
    geom_abline(intercept = 0, slope = 500, linetype = "dotted", color = "orange") +
    geom_abline(intercept = 0, slope = 800, linetype = "dotted", color = "red") +
    labs(title = paste("Cost-Effectiveness Plane:", strategy_name),
         x = "Incremental DALYs Averted",
         y = "Incremental Cost (USD)") +
    theme_minimal()
  
  if(!is.null(ellipse_df)) {
    p <- p + geom_path(data = ellipse_df, aes(x = effect, y = cost), 
                       color = color, size = 1.2, linetype = "dashed")
  }
  
  p <- p + geom_point(aes(x = mean(effect), y = mean(cost)), 
                     size = 4, color = color, shape = 18)
  
  return(p)
}

# Create individual CE planes
p_smc <- create_ce_plane(psa_results, "SMC")
p_vaccine <- create_ce_plane(psa_results, "Vaccine")
p_combined <- create_ce_plane(psa_results, "Combined")

# Display plots
print(p_smc)

print(p_vaccine)

print(p_combined)

Combined CE Plane with All Strategies

combined_data <- rbind(
  data.frame(effect = psa_results$inc_effect_smc, 
             cost = psa_results$inc_cost_smc, 
             Strategy = "SMC"),
  data.frame(effect = psa_results$inc_effect_vaccine, 
             cost = psa_results$inc_cost_vaccine, 
             Strategy = "Vaccine"),
  data.frame(effect = psa_results$inc_effect_combined, 
             cost = psa_results$inc_cost_combined, 
             Strategy = "Combined")
)

combined_data <- combined_data[!is.na(combined_data$effect) & 
                               !is.na(combined_data$cost) & 
                               combined_data$effect > 0, ]

p_combined_all <- ggplot(combined_data, aes(x = effect, y = cost, color = Strategy, fill = Strategy)) +
  geom_point(alpha = 0.2, size = 1) +
  stat_ellipse(level = 0.95, geom = "polygon", alpha = 0.1) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray50") +
  geom_vline(xintercept = 0, linetype = "dashed", color = "gray50") +
  geom_abline(intercept = 0, slope = 100, linetype = "dotted", color = "darkgreen") +
  geom_abline(intercept = 0, slope = 500, linetype = "dotted", color = "orange") +
  geom_abline(intercept = 0, slope = 800, linetype = "dotted", color = "red") +
  labs(title = "Cost-Effectiveness Plane: All Strategies",
       subtitle = "95% confidence ellipses shown | WTP thresholds: $100, $500, $800/DALY",
       x = "Incremental DALYs Averted",
       y = "Incremental Cost (USD)") +
  theme_minimal() +
  scale_color_manual(values = c("SMC" = "#377EB8", "Vaccine" = "#4DAF4A", "Combined" = "#E41A1C")) +
  scale_fill_manual(values = c("SMC" = "#377EB8", "Vaccine" = "#4DAF4A", "Combined" = "#E41A1C")) +
  theme(legend.position = "bottom")

print(p_combined_all)

ICER Distribution

icer_data <- data.frame(
  SMC = psa_results$icer_smc,
  Vaccine = psa_results$icer_vaccine,
  Combined = psa_results$icer_combined
) %>%
  pivot_longer(everything(), names_to = "Strategy", values_to = "ICER") %>%
  filter(!is.na(ICER), ICER <= 5000)

p_icer_dist <- ggplot(icer_data, aes(x = Strategy, y = ICER, fill = Strategy)) +
  geom_violin(alpha = 0.5, trim = TRUE, scale = "width") +
  geom_boxplot(width = 0.2, alpha = 0.8, outlier.size = 0.5) +
  geom_jitter(width = 0.15, alpha = 0.3, size = 0.8) +
  geom_hline(yintercept = 100, linetype = "dotted", color = "darkgreen", size = 1) +
  geom_hline(yintercept = 500, linetype = "dotted", color = "orange", size = 1) +
  geom_hline(yintercept = 800, linetype = "dashed", color = "red", size = 1) +
  labs(title = "ICER Distribution by Strategy",
       subtitle = "Violin plots with boxplots | WTP thresholds: $100, $500, $800 per DALY",
       x = "",
       y = "ICER ($ per DALY averted)") +
  theme_minimal() +
  scale_fill_manual(values = c("SMC" = "#377EB8", "Vaccine" = "#4DAF4A", "Combined" = "#E41A1C")) +
  theme(legend.position = "none") +
  scale_y_continuous(labels = comma, limits = c(0, 2000))

print(p_icer_dist)

Cost-Effectiveness Acceptability Curve (CEAC)

# Create CEAC data
wtp_thresholds <- seq(0, 2000, 10)
ceac_data <- data.frame(
  WTP = wtp_thresholds,
  SMC = sapply(wtp_thresholds, function(wtp) mean(psa_results$icer_smc <= wtp, na.rm = TRUE)),
  Vaccine = sapply(wtp_thresholds, function(wtp) mean(psa_results$icer_vaccine <= wtp, na.rm = TRUE)),
  Combined = sapply(wtp_thresholds, function(wtp) mean(psa_results$icer_combined <= wtp, na.rm = TRUE))
) %>%
  pivot_longer(cols = -WTP, names_to = "Strategy", values_to = "Probability")

p_ceac <- ggplot(ceac_data, aes(x = WTP, y = Probability, color = Strategy, group = Strategy)) +
  geom_line(size = 1.2) +
  geom_ribbon(aes(ymin = 0, ymax = Probability, fill = Strategy), alpha = 0.1) +
  geom_vline(xintercept = 100, linetype = "dotted", color = "darkgreen", size = 0.8) +
  geom_vline(xintercept = 500, linetype = "dotted", color = "orange", size = 0.8) +
  geom_vline(xintercept = 800, linetype = "dashed", color = "red", size = 0.8) +
  annotate("text", x = 100, y = 0.95, label = "$100", size = 3, angle = 90, hjust = -0.2) +
  annotate("text", x = 500, y = 0.95, label = "$500", size = 3, angle = 90, hjust = -0.2) +
  annotate("text", x = 800, y = 0.95, label = "$800", size = 3, angle = 90, hjust = -0.2) +
  labs(title = "Cost-Effectiveness Acceptability Curve (CEAC)",
       subtitle = "Probability of being cost-effective at different willingness-to-pay thresholds",
       x = "Willingness-to-pay threshold ($ per DALY averted)",
       y = "Probability of cost-effectiveness") +
  theme_minimal() +
  scale_color_manual(values = c("SMC" = "#377EB8", "Vaccine" = "#4DAF4A", "Combined" = "#E41A1C")) +
  scale_fill_manual(values = c("SMC" = "#377EB8", "Vaccine" = "#4DAF4A", "Combined" = "#E41A1C")) +
  scale_x_continuous(labels = comma, limits = c(0, 2000)) +
  scale_y_continuous(labels = percent, limits = c(0, 1)) +
  theme(legend.position = "bottom")

print(p_ceac)

ICER Histograms

icer_hist_data <- data.frame(
  ICER = c(psa_results$icer_smc, psa_results$icer_vaccine, psa_results$icer_combined),
  Strategy = rep(c("SMC", "Vaccine", "Combined"), each = nrow(psa_results))
) %>%
  filter(!is.na(ICER), ICER <= 3000)

p_hist <- ggplot(icer_hist_data, aes(x = ICER, fill = Strategy)) +
  geom_histogram(alpha = 0.6, bins = 50, position = "identity") +
  geom_vline(xintercept = 100, linetype = "dotted", color = "darkgreen", size = 0.8) +
  geom_vline(xintercept = 500, linetype = "dotted", color = "orange", size = 0.8) +
  geom_vline(xintercept = 800, linetype = "dashed", color = "red", size = 0.8) +
  facet_wrap(~Strategy, ncol = 1, scales = "free_y") +
  labs(title = "ICER Distribution Histograms",
       subtitle = "Vertical lines: WTP thresholds ($100, $500, $800 per DALY)",
       x = "ICER ($ per DALY averted)",
       y = "Frequency") +
  theme_minimal() +
  scale_fill_manual(values = c("SMC" = "#377EB8", "Vaccine" = "#4DAF4A", "Combined" = "#E41A1C")) +
  theme(legend.position = "none") +
  scale_x_continuous(labels = comma, limits = c(0, 2000))

print(p_hist)

Figures Summary

# Clinical cases plot
clinical_data <- data.frame(
  Strategy = strategy_names,
  Clinical_Cases = sapply(results_list, function(x) x$total_clinical)
)

p1 <- ggplot(clinical_data, aes(x = reorder(Strategy, -Clinical_Cases), 
                                y = Clinical_Cases, fill = Strategy)) +
  geom_bar(stat = "identity", width = 0.7) +
  geom_text(aes(label = format_number(Clinical_Cases)), 
            vjust = -0.5, size = 3.5) +
  labs(title = "Clinical Cases by Strategy (Undiscounted)",
       subtitle = "10-year horizon, 10,000 children",
       x = "", y = "Clinical Cases") +
  theme_minimal() +
  theme(legend.position = "none",
        axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_fill_brewer(palette = "Set2")

print(p1)

# DALYs averted plot
dalys_data <- ce_table[2:4, ]

p2 <- ggplot(dalys_data, aes(x = reorder(Strategy, -DALYs_Averted), 
                             y = DALYs_Averted, fill = Strategy)) +
  geom_bar(stat = "identity", width = 0.7) +
  geom_text(aes(label = format_number(DALYs_Averted)), 
            vjust = -0.5, size = 3.5) +
  labs(title = "DALYs Averted by Strategy (Discounted at 3%)",
       subtitle = "Health outcomes discounted at 3% per annum",
       x = "", y = "DALYs Averted") +
  theme_minimal() +
  theme(legend.position = "none") +
  scale_fill_brewer(palette = "Set2")

print(p2)

# ICER comparison plot
icer_data_plot <- ce_table[2:4, ]
icer_data_plot$CE_Threshold <- ifelse(icer_data_plot$ICER < 800, "Cost-Effective", "Not Cost-Effective")

p3 <- ggplot(icer_data_plot, aes(x = reorder(Strategy, ICER), y = ICER, fill = CE_Threshold)) +
  geom_bar(stat = "identity", width = 0.7) +
  geom_hline(yintercept = 800, linetype = "dashed", color = "red", size = 1) +
  geom_text(aes(label = paste0("$", format_number(ICER))), 
            hjust = -0.1, size = 3.5) +
  labs(title = "Cost-Effectiveness Comparison",
       subtitle = "WTP threshold: $800 per DALY averted (red dashed line)",
       x = "", y = "ICER ($ per DALY averted)") +
  theme_minimal() +
  theme(legend.position = "bottom") +
  scale_fill_manual(values = c("Cost-Effective" = "#4DAF4A", "Not Cost-Effective" = "#E41A1C")) +
  coord_flip()

print(p3)

# Geographic distribution plot
p4 <- ggplot(geo_summary, aes(x = geography, y = DALYs_Discounted/1000, fill = Strategy)) +
  geom_bar(stat = "identity", position = "dodge", width = 0.7) +
  labs(title = "Geographic Distribution of DALYs (Discounted)",
       subtitle = "Discounted at 3% per annum",
       x = "", y = "Discounted DALYs (thousands)") +
  theme_minimal() +
  scale_fill_brewer(palette = "Set1", name = "Intervention") +
  theme(legend.position = "bottom")

print(p4)

BUDGET IMPACT ANALYSIS

# ===================================================================
# BUDGET IMPACT ANALYSIS (BIA) - CORRECTED VERSION
# ===================================================================

# Budget Impact Analysis for Malaria Interventions
# 5-year budget planning with national scale-up scenarios

cat("\n\n========================================\n")
## 
## 
## ========================================
cat("BUDGET IMPACT ANALYSIS\n")
## BUDGET IMPACT ANALYSIS
cat("========================================\n\n")
## ========================================
# ===================================================================
# PART 1: CREATE CE RESULTS
# ===================================================================

    ce_results <- data.frame(
      Strategy = strategy_names,
      Clinical_Cases = sapply(results_list, function(x) x$total_clinical),
      Severe_Cases = sapply(results_list, function(x) x$total_severe),
      Deaths = sapply(results_list, function(x) x$total_deaths),
      DALYs = sapply(results_list, function(x) x$total_dalys),
      Costs = sapply(results_list, function(x) x$total_costs)
    )
    
    ce_results$DALYs_Averted <- ce_results$DALYs[1] - ce_results$DALYs
    ce_results$Inc_Cost <- ce_results$Costs - ce_results$Costs[1]
    ce_results$ICER <- ce_results$Inc_Cost / ce_results$DALYs_Averted
    ce_results$ICER[ce_results$DALYs_Averted <= 0] <- NA
    
    cat("✓ ce_results created successfully\n")
## ✓ ce_results created successfully
# ===================================================================
# PART 2: BUDGET IMPACT PARAMETERS
# ===================================================================

# National population parameters (example country: 5 million children under 5)
national_u5_population <- 5000000
cohort_size <- 10000
scale_factor <- national_u5_population / cohort_size

# Time horizon for budget impact (5 years)
bia_horizon_years <- 5
annual_discount_rate <- 0.03

# Target coverage targets by year (gradual scale-up)
coverage_targets <- data.frame(
  Year = 1:5,
  Vaccine_Urban = c(0.65, 0.70, 0.75, 0.80, 0.85),
  Vaccine_Rural = c(0.40, 0.50, 0.60, 0.70, 0.75),
  SMC_Urban = c(0.55, 0.60, 0.65, 0.70, 0.75),
  SMC_Rural = c(0.45, 0.55, 0.65, 0.70, 0.75),
  ITN_Urban = c(0.70, 0.75, 0.80, 0.85, 0.90),
  ITN_Rural = c(0.45, 0.55, 0.65, 0.70, 0.75)
)

# Population distribution
urban_pop_u5 <- national_u5_population * 0.30  # 30% urban
rural_pop_u5 <- national_u5_population * 0.70  # 70% rural

# ===================================================================
# PART 3: CALCULATE STRATEGY COSTS (5-YEAR, UNDISCOUNTED)
# ===================================================================

# Function to calculate annual costs for a strategy
calculate_strategy_costs <- function(strategy, year) {
  
  # Get coverage for this year
  vaccine_cov_urban <- coverage_targets$Vaccine_Urban[year]
  vaccine_cov_rural <- coverage_targets$Vaccine_Rural[year]
  smc_cov_urban <- coverage_targets$SMC_Urban[year]
  smc_cov_rural <- coverage_targets$SMC_Rural[year]
  itn_cov_urban <- coverage_targets$ITN_Urban[year]
  itn_cov_rural <- coverage_targets$ITN_Rural[year]
  
  # ITN costs (annual distribution, 2-year lifespan)
  itn_cost_per_net <- 2.50
  itn_annual_cost_urban <- urban_pop_u5 * itn_cost_per_net * itn_cov_urban / 2
  itn_annual_cost_rural <- rural_pop_u5 * itn_cost_per_net * itn_cov_rural / 2
  itn_total <- itn_annual_cost_urban + itn_annual_cost_rural
  
  if(strategy == "baseline") {
    return(itn_total)
  }
  
  # SMC costs (annual, children 2-5 years = 27% of U5 population)
  smc_eligible_u5_prop <- 0.27
  smc_cost_per_child <- 6.00
  
  smc_annual_cost_urban <- urban_pop_u5 * smc_eligible_u5_prop * smc_cost_per_child * smc_cov_urban
  smc_annual_cost_rural <- rural_pop_u5 * smc_eligible_u5_prop * smc_cost_per_child * smc_cov_rural
  smc_total <- smc_annual_cost_urban + smc_annual_cost_rural
  
  # Vaccine costs (annual, children 0-24 months = 16% of U5 population)
  vaccine_eligible_u5_prop <- 0.16
  vaccine_cost_per_child <- 26.00
  
  vaccine_annual_cost_urban <- urban_pop_u5 * vaccine_eligible_u5_prop * vaccine_cost_per_child * vaccine_cov_urban
  vaccine_annual_cost_rural <- rural_pop_u5 * vaccine_eligible_u5_prop * vaccine_cost_per_child * vaccine_cov_rural
  vaccine_total <- vaccine_annual_cost_urban + vaccine_annual_cost_rural
  
  # Delivery cost multipliers
  rural_delivery_multiplier <- 1.5
  
  if(strategy == "smc") {
    total <- itn_total + smc_total
  } else if(strategy == "vaccine") {
    total <- itn_total + vaccine_total
  } else if(strategy == "combined") {
    total <- itn_total + smc_total + (vaccine_total * rural_delivery_multiplier)
  } else {
    total <- itn_total
  }
  
  return(total)
}

# ===================================================================
# PART 4: CALCULATE ANNUAL AND CUMULATIVE COSTS
# ===================================================================

# Create budget impact data frame
bia_data <- data.frame(
  Year = 1:bia_horizon_years,
  Baseline_Cost = NA,
  SMC_Cost = NA,
  Vaccine_Cost = NA,
  Combined_Cost = NA,
  Incremental_SMC = NA,
  Incremental_Vaccine = NA,
  Incremental_Combined = NA
)

for(year in 1:bia_horizon_years) {
  bia_data$Baseline_Cost[year] <- calculate_strategy_costs("baseline", year)
  bia_data$SMC_Cost[year] <- calculate_strategy_costs("smc", year)
  bia_data$Vaccine_Cost[year] <- calculate_strategy_costs("vaccine", year)
  bia_data$Combined_Cost[year] <- calculate_strategy_costs("combined", year)
  
  bia_data$Incremental_SMC[year] <- bia_data$SMC_Cost[year] - bia_data$Baseline_Cost[year]
  bia_data$Incremental_Vaccine[year] <- bia_data$Vaccine_Cost[year] - bia_data$Baseline_Cost[year]
  bia_data$Incremental_Combined[year] <- bia_data$Combined_Cost[year] - bia_data$Baseline_Cost[year]
}

# Calculate discounted costs (3% annually)
bia_data$Discount_Factor <- 1 / (1 + annual_discount_rate)^(bia_data$Year - 1)

for(col in c("Baseline_Cost", "SMC_Cost", "Vaccine_Cost", "Combined_Cost",
             "Incremental_SMC", "Incremental_Vaccine", "Incremental_Combined")) {
  bia_data[paste0(col, "_Discounted")] <- bia_data[[col]] * bia_data$Discount_Factor
}

# Calculate cumulative totals
cumulative_bia <- data.frame(
  Strategy = c("Baseline (ITNs)", "SMC + ITNs", "Vaccine + ITNs", "Combined"),
  Total_Undiscounted = c(
    sum(bia_data$Baseline_Cost),
    sum(bia_data$SMC_Cost),
    sum(bia_data$Vaccine_Cost),
    sum(bia_data$Combined_Cost)
  ),
  Total_Discounted = c(
    sum(bia_data$Baseline_Cost_Discounted),
    sum(bia_data$SMC_Cost_Discounted),
    sum(bia_data$Vaccine_Cost_Discounted),
    sum(bia_data$Combined_Cost_Discounted)
  )
)

cumulative_bia$Incremental_Undiscounted <- cumulative_bia$Total_Undiscounted - cumulative_bia$Total_Undiscounted[1]
cumulative_bia$Incremental_Discounted <- cumulative_bia$Total_Discounted - cumulative_bia$Total_Discounted[1]

# Format numbers for display
format_number <- function(x) {
  format(round(x, 0), big.mark = ",", scientific = FALSE)
}

# ===================================================================
# PART 5: ANNUAL BUDGET TABLE
# ===================================================================

cat("\n\n========================================\n")
## 
## 
## ========================================
cat("BUDGET IMPACT ANALYSIS RESULTS\n")
## BUDGET IMPACT ANALYSIS RESULTS
cat("========================================\n\n")
## ========================================
cat("Annual Budget Requirements (5-Year Scale-Up, National Level)\n")
## Annual Budget Requirements (5-Year Scale-Up, National Level)
cat("-----------------------------------------------------------\n\n")
## -----------------------------------------------------------
# Format annual budget table
annual_budget_table <- bia_data %>%
  mutate(
    Year = Year,
    Baseline = paste0("$", format_number(Baseline_Cost / 1e6), "M"),
    SMC = paste0("$", format_number(SMC_Cost / 1e6), "M"),
    Vaccine = paste0("$", format_number(Vaccine_Cost / 1e6), "M"),
    Combined = paste0("$", format_number(Combined_Cost / 1e6), "M"),
    Incremental_Vaccine = paste0("$", format_number(Incremental_Vaccine / 1e6), "M"),
    Incremental_Combined = paste0("$", format_number(Incremental_Combined / 1e6), "M")
  ) %>%
  select(Year, Baseline, SMC, Vaccine, Combined, Incremental_Vaccine, Incremental_Combined)

print(annual_budget_table)
##   Year Baseline  SMC Vaccine Combined Incremental_Vaccine Incremental_Combined
## 1    1      $3M $ 7M    $13M     $22M                $10M                 $19M
## 2    2      $4M $ 8M    $15M     $26M                $12M                 $22M
## 3    3      $4M $10M    $18M     $30M                $13M                 $25M
## 4    4      $5M $10M    $20M     $33M                $15M                 $28M
## 5    5      $5M $11M    $21M     $35M                $16M                 $30M
# ===================================================================
# PART 6: CUMULATIVE BUDGET TABLE
# ===================================================================

cat("\n\nCumulative 5-Year Budget Requirements\n")
## 
## 
## Cumulative 5-Year Budget Requirements
cat("---------------------------------------\n\n")
## ---------------------------------------
cumulative_display <- cumulative_bia %>%
  mutate(
    Total_Undiscounted = paste0("$", format_number(Total_Undiscounted / 1e6), "M"),
    Total_Discounted = paste0("$", format_number(Total_Discounted / 1e6), "M"),
    Incremental_Undiscounted = paste0("$", format_number(Incremental_Undiscounted / 1e6), "M"),
    Incremental_Discounted = paste0("$", format_number(Incremental_Discounted / 1e6), "M")
  )

print(cumulative_display)
##          Strategy Total_Undiscounted Total_Discounted Incremental_Undiscounted
## 1 Baseline (ITNs)              $ 21M            $ 20M                    $  0M
## 2      SMC + ITNs              $ 47M            $ 44M                    $ 25M
## 3  Vaccine + ITNs              $ 87M            $ 82M                    $ 66M
## 4        Combined              $146M            $137M                    $125M
##   Incremental_Discounted
## 1                  $  0M
## 2                  $ 24M
## 3                  $ 62M
## 4                  $117M
# ===================================================================
# PART 7: COST PER DALY BY BUDGET SCENARIO (USING CE_RESULTS)
# ===================================================================

# Safely extract DALYs averted
if(exists("ce_results") && nrow(ce_results) >= 4) {
  dalys_averted_vaccine <- ce_results$DALYs_Averted[3]
  dalys_averted_combined <- ce_results$DALYs_Averted[4]
  
  # Scale to national level
  dalys_averted_national_vaccine <- dalys_averted_vaccine * scale_factor
  dalys_averted_national_combined <- dalys_averted_combined * scale_factor
  
  # Calculate cost per DALY at national level
  cost_per_daly_vaccine <- cumulative_bia$Total_Discounted[3] / dalys_averted_national_vaccine
  cost_per_daly_combined <- cumulative_bia$Total_Discounted[4] / dalys_averted_national_combined
} else {
  # Default values if ce_results not available
  dalys_averted_national_vaccine <- 13780 * scale_factor / 10000
  dalys_averted_national_combined <- 21950 * scale_factor / 10000
  cost_per_daly_vaccine <- cumulative_bia$Total_Discounted[3] / dalys_averted_national_vaccine
  cost_per_daly_combined <- cumulative_bia$Total_Discounted[4] / dalys_averted_national_combined
}

budget_scenarios <- data.frame(
  Scenario = c("Base Case", "Optimistic (20% lower costs)", 
               "Pessimistic (20% higher costs)", "High Coverage (90% target)"),
  Vaccine_Cost_Per_DALY = c(
    cost_per_daly_vaccine,
    cost_per_daly_vaccine * 0.8,
    cost_per_daly_vaccine * 1.2,
    cost_per_daly_vaccine * 0.85
  ),
  Combined_Cost_Per_DALY = c(
    cost_per_daly_combined,
    cost_per_daly_combined * 0.8,
    cost_per_daly_combined * 1.2,
    cost_per_daly_combined * 0.85
  ),
  Vaccine_Budget_M = c(
    cumulative_bia$Total_Discounted[3] / 1e6,
    cumulative_bia$Total_Discounted[3] / 1e6 * 0.8,
    cumulative_bia$Total_Discounted[3] / 1e6 * 1.2,
    cumulative_bia$Total_Discounted[3] / 1e6 * 1.1
  ),
  Combined_Budget_M = c(
    cumulative_bia$Total_Discounted[4] / 1e6,
    cumulative_bia$Total_Discounted[4] / 1e6 * 0.8,
    cumulative_bia$Total_Discounted[4] / 1e6 * 1.2,
    cumulative_bia$Total_Discounted[4] / 1e6 * 1.1
  )
)

cat("\n\nBudget Scenario Analysis\n")
## 
## 
## Budget Scenario Analysis
cat("========================\n\n")
## ========================
print(budget_scenarios)
##                         Scenario Vaccine_Cost_Per_DALY Combined_Cost_Per_DALY
## 1                      Base Case              133.8743               140.8530
## 2   Optimistic (20% lower costs)              107.0994               112.6824
## 3 Pessimistic (20% higher costs)              160.6491               169.0236
## 4     High Coverage (90% target)              113.7931               119.7250
##   Vaccine_Budget_M Combined_Budget_M
## 1         81.89784          136.8507
## 2         65.51827          109.4805
## 3         98.27740          164.2208
## 4         90.08762          150.5358
# ===================================================================
# PART 8: FINANCIAL SUSTAINABILITY ANALYSIS
# ===================================================================

# Calculate percentage of health budget
assumed_health_budget_million <- 5000  # $5 billion annual health budget
health_budget_share <- cumulative_bia$Total_Discounted[4] / 1e6 / (assumed_health_budget_million * bia_horizon_years) * 100

# Calculate cost per child per year
cost_per_child_vaccine <- cumulative_bia$Total_Discounted[3] / national_u5_population / bia_horizon_years
cost_per_child_combined <- cumulative_bia$Total_Discounted[4] / national_u5_population / bia_horizon_years

cat("\n\nFinancial Sustainability Indicators\n")
## 
## 
## Financial Sustainability Indicators
cat("=====================================\n\n")
## =====================================
cat(sprintf("Cost per child per year (Vaccine strategy): $%.2f\n", cost_per_child_vaccine))
## Cost per child per year (Vaccine strategy): $3.28
cat(sprintf("Cost per child per year (Combined strategy): $%.2f\n", cost_per_child_combined))
## Cost per child per year (Combined strategy): $5.47
cat(sprintf("Share of annual health budget (Combined): %.2f%%\n", health_budget_share))
## Share of annual health budget (Combined): 0.55%
if(exists("dalys_averted_national_vaccine")) {
  cat(sprintf("Total DALYs averted nationally (Vaccine): %s\n", format_number(dalys_averted_national_vaccine)))
  cat(sprintf("Total DALYs averted nationally (Combined): %s\n", format_number(dalys_averted_national_combined)))
}
## Total DALYs averted nationally (Vaccine): 611,752
## Total DALYs averted nationally (Combined): 971,585
cat(sprintf("Cost per DALY averted (Vaccine): $%.0f\n", cost_per_daly_vaccine))
## Cost per DALY averted (Vaccine): $134
cat(sprintf("Cost per DALY averted (Combined): $%.0f\n", cost_per_daly_combined))
## Cost per DALY averted (Combined): $141
# ===================================================================
# PART 9: FUNDING SCENARIOS
# ===================================================================

funding_scenarios <- data.frame(
  Scenario = c("Current Funding Only", "Gavi Support Added", "Domestic + Gavi", "Full Domestic"),
  Annual_Gap_Vaccine_M = c(
    max(0, cumulative_bia$Total_Discounted[3]/bia_horizon_years/1e6 - 10),
    max(0, cumulative_bia$Total_Discounted[3]/bia_horizon_years/1e6 - 25),
    max(0, cumulative_bia$Total_Discounted[3]/bia_horizon_years/1e6 - 40),
    cumulative_bia$Total_Discounted[3]/bia_horizon_years/1e6
  ),
  Annual_Gap_Combined_M = c(
    max(0, cumulative_bia$Total_Discounted[4]/bia_horizon_years/1e6 - 10),
    max(0, cumulative_bia$Total_Discounted[4]/bia_horizon_years/1e6 - 25),
    max(0, cumulative_bia$Total_Discounted[4]/bia_horizon_years/1e6 - 40),
    cumulative_bia$Total_Discounted[4]/bia_horizon_years/1e6
  )
)

cat("\n\nFunding Gap Analysis (Annual)\n")
## 
## 
## Funding Gap Analysis (Annual)
cat("==============================\n\n")
## ==============================
print(funding_scenarios)
##               Scenario Annual_Gap_Vaccine_M Annual_Gap_Combined_M
## 1 Current Funding Only             6.379567             17.370137
## 2   Gavi Support Added             0.000000              2.370137
## 3      Domestic + Gavi             0.000000              0.000000
## 4        Full Domestic            16.379567             27.370137
# ===================================================================
# PART 10: BUDGET IMPACT VISUALIZATIONS
# ===================================================================

# Plot 1: Annual budget comparison by strategy
p_budget_annual <- ggplot(bia_data, aes(x = Year)) +
  geom_line(aes(y = Baseline_Cost / 1e6, color = "Baseline (ITNs)"), size = 1.2) +
  geom_line(aes(y = SMC_Cost / 1e6, color = "SMC + ITNs"), size = 1.2) +
  geom_line(aes(y = Vaccine_Cost / 1e6, color = "Vaccine + ITNs"), size = 1.2) +
  geom_line(aes(y = Combined_Cost / 1e6, color = "Combined"), size = 1.2) +
  labs(title = "Annual Budget Requirements by Strategy (Undiscounted)",
       subtitle = "5-year gradual scale-up to target coverage | National: 5M children",
       x = "Year", y = "Annual Cost (Millions USD)") +
  theme_minimal() +
  scale_color_manual(values = c("Baseline (ITNs)" = "gray50", 
                                "SMC + ITNs" = "#377EB8", 
                                "Vaccine + ITNs" = "#4DAF4A", 
                                "Combined" = "#E41A1C"),
                     name = "Strategy") +
  theme(legend.position = "bottom")

# Plot 2: Incremental budget over baseline
p_budget_incremental <- ggplot(bia_data, aes(x = Year)) +
  geom_area(aes(y = Incremental_Vaccine / 1e6, fill = "Vaccine + ITNs"), alpha = 0.6) +
  geom_area(aes(y = Incremental_Combined / 1e6, fill = "Combined"), alpha = 0.6) +
  geom_line(aes(y = Incremental_Vaccine / 1e6, color = "Vaccine + ITNs"), size = 1.2) +
  geom_line(aes(y = Incremental_Combined / 1e6, color = "Combined"), size = 1.2) +
  labs(title = "Incremental Budget Requirements vs Baseline",
       subtitle = "Additional funding needed above current ITN spending",
       x = "Year", y = "Incremental Annual Cost (Millions USD)") +
  theme_minimal() +
  scale_fill_manual(values = c("Vaccine + ITNs" = "#4DAF4A", "Combined" = "#E41A1C"),
                    name = "Strategy") +
  scale_color_manual(values = c("Vaccine + ITNs" = "#4DAF4A", "Combined" = "#E41A1C"),
                     name = "Strategy", guide = "none") +
  theme(legend.position = "bottom")

# Plot 3: Cumulative budget bar chart
p_budget_cumulative <- ggplot(cumulative_bia, aes(x = Strategy, y = Total_Discounted / 1e6, fill = Strategy)) +
  geom_bar(stat = "identity", width = 0.7) +
  geom_text(aes(label = paste0("$", format_number(Total_Discounted / 1e6), "M")), 
            vjust = -0.5, size = 3.5) +
  labs(title = "Cumulative 5-Year Budget Requirements (Discounted at 3%)",
       subtitle = "National scale: 5 million children under 5",
       x = "", y = "Total Cost (Millions USD)") +
  theme_minimal() +
  scale_fill_manual(values = c("Baseline (ITNs)" = "gray50",
                               "SMC + ITNs" = "#377EB8",
                               "Vaccine + ITNs" = "#4DAF4A",
                               "Combined" = "#E41A1C"),
                    name = "Strategy") +
  theme(legend.position = "none")

# Plot 4: Coverage scale-up trajectories
coverage_long <- coverage_targets %>%
  pivot_longer(cols = -Year, names_to = "Setting", values_to = "Coverage") %>%
  separate(Setting, into = c("Intervention", "Geography"), sep = "_")

p_coverage_scaleup <- ggplot(coverage_long, aes(x = Year, y = Coverage, color = Intervention, linetype = Geography)) +
  geom_line(size = 1.2) +
  geom_point(size = 3) +
  labs(title = "Coverage Scale-Up Trajectories",
       subtitle = "Gradual increase to target coverage over 5 years",
       x = "Year", y = "Coverage (%)") +
  theme_minimal() +
  scale_color_manual(values = c("Vaccine" = "#4DAF4A", "SMC" = "#377EB8", "ITN" = "gray50"),
                     name = "Intervention") +
  scale_linetype_manual(values = c("Urban" = "solid", "Rural" = "dashed"),
                        name = "Geography") +
  scale_y_continuous(labels = scales::percent_format(scale = 1), limits = c(0, 1)) +
  theme(legend.position = "bottom")

# Save budget impact plots (only if not in R Markdown rendering)
if(!interactive() || !exists("knitr")) {
  ggsave("BIA_Annual_Budget.png", p_budget_annual, width = 10, height = 6)
  ggsave("BIA_Incremental_Budget.png", p_budget_incremental, width = 10, height = 6)
  ggsave("BIA_Cumulative_Budget.png", p_budget_cumulative, width = 10, height = 7)
  ggsave("BIA_Coverage_ScaleUp.png", p_coverage_scaleup, width = 10, height = 6)
}

# Display plots
print(p_budget_annual)

print(p_budget_incremental)

print(p_budget_cumulative)

print(p_coverage_scaleup)

# ===================================================================
# PART 11: PRINT SUMMARY
# ===================================================================

cat("\n\n========================================\n")
## 
## 
## ========================================
cat("BUDGET IMPACT ANALYSIS COMPLETE\n")
## BUDGET IMPACT ANALYSIS COMPLETE
cat("========================================\n")
## ========================================
cat("\nKey Budget Findings:\n")
## 
## Key Budget Findings:
cat("--------------------\n")
## --------------------
cat(sprintf("• Vaccine + ITNs 5-year cost: $%.1f million (discounted)\n", cumulative_bia$Total_Discounted[3] / 1e6))
## • Vaccine + ITNs 5-year cost: $81.9 million (discounted)
cat(sprintf("• Combined strategy 5-year cost: $%.1f million (discounted)\n", cumulative_bia$Total_Discounted[4] / 1e6))
## • Combined strategy 5-year cost: $136.9 million (discounted)
cat(sprintf("• Additional funding needed for vaccine: $%.1f million\n", cumulative_bia$Incremental_Discounted[3] / 1e6))
## • Additional funding needed for vaccine: $62.1 million
cat(sprintf("• Additional funding needed for combined: $%.1f million\n", cumulative_bia$Incremental_Discounted[4] / 1e6))
## • Additional funding needed for combined: $117.1 million
cat(sprintf("• Cost per child per year (vaccine): $%.2f\n", cost_per_child_vaccine))
## • Cost per child per year (vaccine): $3.28
cat(sprintf("• Cost per DALY averted (vaccine): $%.0f\n", cost_per_daly_vaccine))
## • Cost per DALY averted (vaccine): $134
cat("\nPolicy Implications:\n")
## 
## Policy Implications:
cat("--------------------\n")
## --------------------
if(cost_per_daly_vaccine < 800) {
  cat("✓ Vaccine strategy is cost-effective and financially feasible\n")
}
## ✓ Vaccine strategy is cost-effective and financially feasible
if(cumulative_bia$Incremental_Discounted[4] / 1e6 > 1000) {
  cat("⚠️  Combined strategy requires substantial additional funding (>$1B)\n")
  cat("   Consider phased implementation: start with vaccine, add SMC later\n")
}

cat("\nGenerated budget impact plots:\n")
## 
## Generated budget impact plots:
cat("  - BIA_Annual_Budget.png\n")
##   - BIA_Annual_Budget.png
cat("  - BIA_Incremental_Budget.png\n")
##   - BIA_Incremental_Budget.png
cat("  - BIA_Cumulative_Budget.png\n")
##   - BIA_Cumulative_Budget.png
cat("  - BIA_Coverage_ScaleUp.png\n")
##   - BIA_Coverage_ScaleUp.png