ImpactSimul is an Agent Based Model aimed at helping estimate the impact of an intervention in an HIV program, using a simple and tractable approach. It was first developed to estimate the impact to be expected from Solthis’ Empower II program. It is written in R.
You can install ImpactSimul from GitHub just by running:
# install.packages("devtools")
devtools::install_github("grlurton/ImpactSimul")
To obtain epidemiological data on a country, ImpactSim uses a Python
script that queries the UNAIDS database and gets standardized data. To
get this running, we need to set-up a python environment and download
chromedriver. You shouldn’t have to write any line of Python and will
use the script unaids_scrap.py
which you can find under /utils
in in
this repo which you can put into the utils
directory in your project’s
folder..
We suggest installing Python using Anaconda. 1. Go to https://www.anaconda.com/products/individual 2. Download the appropriate installer for your operating system. 3.Just double-click the downloaded file. In most cases, you can just keep all default options in the installer.
To install the Python libraries you’ll need for the extraction, you just
need to install the conda environment ImpactSimulEnv.yml
which you can
find under /utils
in this repo.
Once you have downloaded it, just open a terminal in the directory you have downloaded it in, and run the following code.
conda env create -f ImpactSimulEnv.yml -n ImpactSimul
utils
directory in
your project’s folderlibrary(ImpactSimul)
library("readxl")
library(dplyr)
library(yaml)
library(reticulate)
library(dplyr)
download_data <- TRUE
run_life_table <- TRUE
n_sim <- 1000
time.unit <- 7
The last block here represents important parameters for the simulation.
download_data
determines whether to download contextual data from
UNAIDS, run_life_table
indicates if the script should format the life
table to include in the population simulation. n_sim
indidcates the
number of simulations to run, time.unit
indicates the number of days
in a step of simulation (ie: 7 corresponds to a week).
The next bit of codes then calls on the data to be formated and extracted if the parameters have been set to do so.
###############################
##### Set up the life table ###
###############################
if(run_life_table){
lt_male <- read_excel("data/lifeTables_SierraLeone.xlsx", sheet = "Male")
lt_female <- read_excel("data/lifeTables_SierraLeone.xlsx", sheet = "Male")
lt <- prep_life_tables(lt_male, lt_female, "data/ltSierraLeone.rds")
}
###############################
##### Download UNAIDS data ####
###############################
if(download_data){
extract_unaids("ImpactSimul", "utils/unaids_scrap.py", "Sierra Leone", "utils/chromedriver", "data/unaids_estimates/")
}
It is then time to load the biological parameters and the parameters defining the different scenarios to simulate and compare, as well as the epidemiologic data downloaded from UNAIDS.
####################################
### Loading different parameters ###
####################################
parameters_bio <- yaml.load_file("params/parameters_bio.yaml")
list_scenarios <- create_scenario_list()
#############################
### Loading external data ###
#############################
# estimates UNAIDS
data <- readRDS("data/unaids_estimates/SierraLeone/UNAIDS_estimates_SierraLeone.rds")
prop_male <- data$MeanNum[grepl(pattern = "Men aged 15 and over newly infected with HIV ",
x = data$indic)]/data$MeanNum[grepl(pattern = "Adults aged 15 and over newly infected with HIV",
x = data$indic)]
All parameters are loaded and formated : TIME TO RUN A SIMULATION !!!
We start by loading the parameters set in the differnet previous stages.
Note the size of the cohort is set in object init
.
##############################
### Running the simulation ###
##############################
param <- params(time.unit = time.unit)
init <- init(i.prev.male = 1,
i.prev.feml = 1,
max.inf.time = 15 * 365,
n=2655)
## Here, this loop takes all the scenarios found in the folder with the scenarios yaml, and runs them one ## by one, keeping the results in separate objects.
for(scenario_simulation in names(list_scenarios)){
print(scenario_simulation)
assign(paste0("result_", scenario_simulation), run_simulations(init, param, scenario_simulation, intervention_start = 0, prop_male, nsteps = 52 * 5, nsim = n_sim))
}
The results objects are finally post-processed and put into summary objects. The results can also be translated into DALYs.
# Simulation Results for the different scenarios
res_0 <- summary_outcomes(result_parameters_baseline)
res_1 <- summary_outcomes(result_parameters_intervention)
# Combined
res <- bind_rows(
tibble(
Death = res_0$death$deaths,
simul = res_0$death$simul,
`New infection` = res_0$newInf$newInf,
`Lost to follow-up` = res_0$LTFU$LTFU,
`On treatment` = res_0$onTrt$onTrt,
`Virally suppressed` = res_0$VlSupp$VlSupp,
`AIDS on treatment` = res_0$AidsonART$AidsonART,
`AIDS off treatment` = res_0$AidsoffART$AidsoffART,
time = res_0$death$time,
scenario = "baseline"
),
tibble(
Death = res_1$death$deaths,
simul = res_1$death$simul,
`New infection` = res_1$newInf$newInf,
`Lost to follow-up` = res_1$LTFU$LTFU,
`On treatment` = res_1$onTrt$onTrt,
`Virally suppressed` = res_1$VlSupp$VlSupp,
`AIDS on treatment` = res_1$AidsonART$AidsonART,
`AIDS off treatment` = res_1$AidsoffART$AidsoffART,
time = res_1$death$time,
scenario = "intervention"
)
)
##DALYs Estimations for the different scenarios
DALYs_0 <- calculate_DALYs(res_0, parameters_bio, param)
DALYs_1 <- calculate_DALYs(res_1, parameters_bio, param)
# Combined
daly <- bind_rows(
tibble(
dalys = DALYs_0$DALYs,
scenario = "baseline"
),
tibble(
dalys = DALYs_1$DALYs,
scenario = "intervention"
)
)
Finally, making visualizations for better analysis of the results and export import reslus
make_pyramid(res_0)
result_comparison_plot(res)
# Writing results to csv
table_out <-compare_table(res, "baseline", "intervention")
write.csv(table_out, "data/results/table_results.csv")
DALY_comparison(daly)
## mean effect and 95% empirical confidence interval
c(mean(DALYs_0$DALYs - DALYs_1$DALYs),
quantile(DALYs_0$DALYs - DALYs_1$DALYs, .025),
quantile(DALYs_0$DALYs - DALYs_1$DALYs, .975)
)
ImpactSimul
uses Agent Based Simulation (ABM) in which individual
patients are being created, and their evolution is simulated in time
through multiple steps. This approach is flexibe, and allows to estimate
the impact of the modification of some hypothesis underlying the
parameters used to make the population evolve in time, such as, for
example, the average mortality rate or other characteristics.
ImpactSimul
uses a model in which patients can enter at any period
during the time of the simulation. He then undergoes a series of
transitions going through acute, asymptomatic and symptomatic HIV
infection. At each period, he has an occasion to enter the care system,
and to evolve through it.
Depending on the hypothesis that will be made for each of these transitions, we will have different outcomes at the end of the program. This is why a key aspect of running ImpactSimul and to analyze its results lies in the hypothesis that we will be making on each transition.
The set of parameters are supposed to be indicative of different domains of HIV programs that can be modified by a program. This set is as follows:
The different parameters can be specified in yaml files that can be
stored under params/scenarios
in your project (or another directory to
be stipulated). An example file is provided on this
repo.
The top panel shows the evolution over time of 6 key indicators of the HIV epidemics for the simulated cohort during the study period. The curves represent the average value of these indicators over the simulations for the baseline and intervention scenarios separately;the shaded regions around these curves represent the uncertainty.
The bottom panel shows the total number of deaths and new infections by scenario across the simulations. The peak of the two distributions showcases the most likely number of death and new infection in both scenarios according to the simulations; the width of the distributions highlights the uncertainty in the number of deaths and new infections across the simulations.
Each agent participating in the simulation is in either of these 4 states: HIV case, AIDS case not on ART, AIDS case on ART, dead.
Years of life with disability (YLD): we calculate the number of years of life with disability for each agent as the number of years in each of the 3 living states multiplied by the disability weight associated with that state (.135 for HIV infected, .505 for AIDS case not on ART, .167 for AIDS case on ART - see GBD reference for weights). We sum individual YLD across all agents in each simulation to get the total number of YLD per simulation.
Years of life lost (YLL): we calculate the number of years of life lost for each agent as the difference between the end of the study period and the date of death. If the agent is alive at the end of the simulation, its contribution to the YLL is 0. We sum individual YLL across all agents in each simulation to get the total number of YLD per simulation.
DALYs: DALYs are calculated for each simulation by adding the number of YLD and YLL.
For example, a HIV-infected agent in the simulation for 2.5 years before developing AIDS, initiated on ART 1.5 years after developing AIDS, and dying 2 years later and 1.3 years before the end of the study period will contribute to: (2.5.135 + 1.5.505 + 2*.167) + 1.3 = 2.729 DALYs
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.