| Title: | Nelson's Treatment Centre Simulation in Simmer |
|---|---|
| Description: | A discrete-event simulation of a simple urgent care treatment centre simulation from Nelson (2013). Implemented in R Simmer. The model is packaged to allow for easy experimentation, summary of results, and implementation in other software such as a Shiny interface. |
| Authors: | Thomas Monks [aut, cre] (ORCID: <https://orcid.org/0000-0003-2631-4481>) |
| Maintainer: | Thomas Monks <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.3.0 |
| Built: | 2026-05-13 08:12:41 UTC |
| Source: | https://github.com/pythonhealthdatascience/stars-treat-simmer |
Returns the number of arrivals by replication as a data.frame
arrivals_by_replication(envs)arrivals_by_replication(envs)
envs |
simmer environments |
data.frame
Simulates the arrival of a patient, assigns a patient type and selects treatment trajectory.
create_arrival_generator(exp)create_arrival_generator(exp)
exp |
An experiment in list form - contains all model parameters. Use treat.sim::create_experiment() to generate an experiment list. |
a simmer trajectory
[create_experiment()] to create list containing default and custom experimental parameters.
default_exp <- create_experiment() patient_generator <- create_arrival_generator(default_exp)default_exp <- create_experiment() patient_generator <- create_arrival_generator(default_exp)
Create and return a list containing all of the parameters used by the treat.sim model.
create_experiment( n_triage_bays = DEFAULT_N_TRIAGE, n_reg_clerks = DEFAULT_N_REG, n_exam_rooms = DEFAULT_N_EXAM, n_trauma_rooms = DEFAULT_N_TRAUMA, n_non_trauma_cubicles = DEFAULT_NON_TRAUMA_CUBICLES, n_trauma_cubicles = DEFAULT_TRAUMA_CUBICLES, triage_mean = DEFAULT_TRIAGE_MEAN, stabilisation_mean = DEFAULT_TRAUMA_MEAN, trauma_treat_params = DEFAULT_TRAUMA_TREATMENT_PARAMS, reg_params = DEFAULT_REG_PARAMS, exam_params = DEFAULT_EXAM_PARAMS, prob_non_trauma_treat = DEFAULT_NON_TRAUMA_TREAT_P, nontrauma_treat_params = DEFAULT_NON_TRAUMA_TREATMENT_PARAMS, prob_trauma = DEFAULT_PROB_TRAUMA, arrival_profile = nelson_arrivals, log_level = LOG_LEVEL )create_experiment( n_triage_bays = DEFAULT_N_TRIAGE, n_reg_clerks = DEFAULT_N_REG, n_exam_rooms = DEFAULT_N_EXAM, n_trauma_rooms = DEFAULT_N_TRAUMA, n_non_trauma_cubicles = DEFAULT_NON_TRAUMA_CUBICLES, n_trauma_cubicles = DEFAULT_TRAUMA_CUBICLES, triage_mean = DEFAULT_TRIAGE_MEAN, stabilisation_mean = DEFAULT_TRAUMA_MEAN, trauma_treat_params = DEFAULT_TRAUMA_TREATMENT_PARAMS, reg_params = DEFAULT_REG_PARAMS, exam_params = DEFAULT_EXAM_PARAMS, prob_non_trauma_treat = DEFAULT_NON_TRAUMA_TREAT_P, nontrauma_treat_params = DEFAULT_NON_TRAUMA_TREATMENT_PARAMS, prob_trauma = DEFAULT_PROB_TRAUMA, arrival_profile = nelson_arrivals, log_level = LOG_LEVEL )
n_triage_bays |
Number of triage bays |
n_reg_clerks |
Number of booking clerks |
n_exam_rooms |
Number of exam rooms |
n_trauma_rooms |
Number of trauma rooms for stabilisation |
n_non_trauma_cubicles |
Number of non-trauma treatment cubicles |
n_trauma_cubicles |
Number of trauma treatment cubicles |
triage_mean |
Mean triage duration (exponential distribution) |
stabilisation_mean |
Mean trauma stabilisation time (exponential distribution) |
trauma_treat_params |
list - mu and sigma for trauma treatment (lognormal) |
reg_params |
list - mu and signma for registration (lognormal) |
exam_params |
list mu and sigma for examination time (normal) |
prob_non_trauma_treat |
probability trauma patient requires treatment |
nontrauma_treat_params |
list - mu and signma for non trauma cubicle treatment (lognormal) |
prob_trauma |
probability arrival has trauma injuries |
arrival_profile |
time dependent arrival profile The default value used is the package internal datset 'nelson_arrivals'. A new dataset should include three columns: 1. period (equally spaced 60 min intervals 0 to 1020) 2. arrival_rate (per hour) 3. arrival_rate2 (per minute) |
log_level |
simmer log level. Set to 0 to hide all debug info as model runs. |
If no parameters are passed to the function then a default experiment is created.
Users can choose to create custom experiments by passing values to the corresponding parameters in the function.
A list
# sample from Nelson arrivals at time 20.0 default_experiment <- create_experiment() # set number of triage bays to 3 default_experiment <- create_experiment(n_triage_bays=3)# sample from Nelson arrivals at time 20.0 default_experiment <- create_experiment() # set number of triage bays to 3 default_experiment <- create_experiment(n_triage_bays=3)
Simulates the process for a non-trauma patient. Logic is:
1. Triage (requires triage bay)
2. Registriation (requires clert)
3. Examination (requires exam room)
4. Probabilistic decision about treatment
4.1. Treatment (requires cubicle)
5. Discharge
create_non_trauma_pathway(exp)create_non_trauma_pathway(exp)
exp |
An experiment in list form - contains all model parameters. Use treat.sim::create_experiment() to generate an experiment list. |
a simmer trajectory
[create_experiment()] to create list containing default and custom experimental parameters.
default_exp <- create_experiment() nt_traj <- create_non_trauma_pathway(default_exp)default_exp <- create_experiment() nt_traj <- create_non_trauma_pathway(default_exp)
Simulates cubicle treatment of trauma patients (log normally distributed time)
create_nt_cubicle_treatment(exp)create_nt_cubicle_treatment(exp)
exp |
An experiment in list form - contains all model parameters. Use treat.sim::create_experiment() to generate an experiment list. |
a simmer trajectory
[create_experiment()] to create list containing default and custom experimental parameters.
default_exp <- create_experiment() nt_treatement_traj <- create_nt_cubicle_treatment(default_exp)default_exp <- create_experiment() nt_treatement_traj <- create_nt_cubicle_treatment(default_exp)
Accepts a table of replication results and returns the mean of those values in a data.frame
create_summary_table(rep_table, dp = 2)create_summary_table(rep_table, dp = 2)
rep_table |
data.frame containing replications (rows) and KPIs (cols) |
dp |
the number of decimal places |
data.frame
[replication_results_table()] to create a table of replications
Trauma patients follow this process in the trajectory:
1. Triage (requires triage bay)
2. Stabilisation (requires trauma room)
3. Treatment (requirement trauma cubicle)
4. Discharge
create_trauma_pathway(exp)create_trauma_pathway(exp)
exp |
An experiment in list form - contains all model parameters. Use treat.sim::create_experiment() to generate an experiment list. |
a simmer trajectory
[create_experiment()] to create list containing default and custom experimental parameters.
default_exp <- create_experiment() trauma_traj <- create_trauma_pathway(default_exp)default_exp <- create_experiment() trauma_traj <- create_trauma_pathway(default_exp)
Accepts a table of replication results and a ggplot histogram object for a selected column.
histogram_of_replications(rep_table, column_name, unit_label, n_bins = 10)histogram_of_replications(rep_table, column_name, unit_label, n_bins = 10)
rep_table |
data.frame containing replications (rows) and KPIs (cols) |
column_name |
string name of the KPI to plot |
unit_label |
string of the x-axis label unit |
n_bins |
number of bins for the histogram |
plot
[replication_results_table()] to create a table of replications
The function runs single_run in a loop and returns the list of environments from each replication. The result can be used for analysis of the model
multiple_replications(exp, n_reps = 5, random_seed = 0)multiple_replications(exp, n_reps = 5, random_seed = 0)
exp |
An experiment in list form - contains all model parameters. |
n_reps |
number of replications to run. |
random_seed |
the random seed for the reps |
a list of simmer environments
[single_run()] to perform a single replication with the model
exp <- create_experiment(log_level=0) # run 50 replications of the model reps <- multiple_replications(exp, n_reps=50, random_seed=0)exp <- create_experiment(log_level=0) # run 50 replications of the model reps <- multiple_replications(exp, n_reps=50, random_seed=0)
A simple default arrival profile for use with treat.sim
nelson_arrivalsnelson_arrivals
## 'nelson_arrivals' This is a data.frame containing the following columns
0 to 480 in 60 minute intervals
rate per hour
rate per minute
'https://raw.githubusercontent.com/TomMonks/open-science-for-sim/main/src/notebooks/01_foss_sim/data/ed_arrivals.csv'
Calculates the mu and sigma of the normal distribution underlying a lognormal
normal_moments_from_lognormal(mean, std)normal_moments_from_lognormal(mean, std)
mean |
A number. Sample mean. |
std |
A number. Sample standard deviation |
'rlnorm' from 'stats' is designed to sample from the lognormal distribution. The parameters is expects are moments of the underlying normal distribution Using sample mean and standard deviation this function calculates the mu and sigma of the normal distribution.
A list containing mu and sigma
https://blogs.sas.com/content/iml/2014/06/04/simulate-lognormal-data-with-specified-mean-and-variance.html
normal_moments_from_lognormal(mean = 125.0, std = 5.0)normal_moments_from_lognormal(mean = 125.0, std = 5.0)
Use the current simulation time to sample an appropriate inter-arrival time from a user set NSPP. Assumes equal spaced intervals.
nspp_thinning(simulation_time, arrival_profile, debug = FALSE)nspp_thinning(simulation_time, arrival_profile, debug = FALSE)
simulation_time |
A number. The current simulation time |
arrival_profile |
A data.frame The time dependent arrival profile |
debug |
bool. TRUE = printout log of thinning after a sample has been accepted. FALSE = no debug info provided. |
Thinning is an acceptance-rejection approach to sampling inter-arrival times (IAT) from a time dependent distribution where each time period follows its own exponential distribution.
There are two random variables employed in sampling: an exponential distribution (used to sample IAT) and a uniform distribution (used to accept/reject samples).
All IATs are sampled from an Exponential distribution with the highest arrival rate (most frequent). These arrivals are then rejected (thinned) proportional to the ratio of the current arrival rate to the maximum arrival rate. The algorithm executes until a sample is accepted. The IAT returned is the sum of all the IATs that were sampled.
A number
# sample from Nelson arrivals at time 20.0 nspp_thinning(20.0, nelson_arrivals, debug=TRUE)# sample from Nelson arrivals at time 20.0 nspp_thinning(20.0, nelson_arrivals, debug=TRUE)
Accepts a list of simmer environments and converts to a data,frame of replications (rows) x KPIs (cols).
replication_results_table( reps, exp, results_collection_period = DEFAULT_RESULTS_COLLECTION_PERIOD )replication_results_table( reps, exp, results_collection_period = DEFAULT_RESULTS_COLLECTION_PERIOD )
reps |
list of simmer environments |
exp |
list of "experiment" contains all of the model parameters used to create the results |
results_collection_period |
the length of time results were collected. |
data.frame
Returns the utilisation of resource by replication as a data.frame calculation: total busy time / total scheduled resource time. where total scheduled time = n_resource * results collection period.
resource_utilisation_by_replication(reps, exp, results_collection_period)resource_utilisation_by_replication(reps, exp, results_collection_period)
exp |
list of parameters for experiment |
results_collection_period |
results collection simulation time |
envs |
simmer environments |
data.frame
Returns the mean waiting times for resourcse by replication as a data.frame
resource_waiting_times_by_replication(reps)resource_waiting_times_by_replication(reps)
envs |
simmer environments from each replication of the model |
data.frame
'sample_arrival_type' samples if a patient type is trauma or non-trauma with a given probability.
sample_arrival_type(p, n = 1)sample_arrival_type(p, n = 1)
p |
A number: the probability a patient has trauma on arrival |
n |
A number: number of samples to generate. |
The function uses the Bernoulli distribution (Rlab) to sample if a patient is Trauma or Non-Trauma. The return values are 1 = Trauma, 2 = Non-trauma.
patient_type = sample_arrival_type(0.4)patient_type = sample_arrival_type(0.4)
'sample_nt_trauma_treatment' samples if a non-trauma patient requires cubicle treatment
sample_nt_trauma_treatment(p)sample_nt_trauma_treatment(p)
p |
A number: The probability the patient requires treatment |
The function uses the Bernouli distribution (Rlab) to sample if a patient is requires treatment or not. The return values are 1 = Treatment, 0 = No treatment
treat_flag = sample_nt_trauma_treatment(0.30)treat_flag = sample_nt_trauma_treatment(0.30)
The function adds treat.sim resources to an environment. The model is then run for a single replication. The environment is returned for use in results analysis.
single_run( exp, rep_number = 1, run_length = DEFAULT_RESULTS_COLLECTION_PERIOD, debug_arrivals = FALSE )single_run( exp, rep_number = 1, run_length = DEFAULT_RESULTS_COLLECTION_PERIOD, debug_arrivals = FALSE )
exp |
An experiment in list form - contains all model parameters. |
rep_number |
the replication number (default=1) |
run_length |
run length of the simulation (default=1020 minutes) |
debug_arrivals |
boolean flag to show debug info for the thinning process Use treat.sim::create_experiment() to generate an experiment list. |
a simmer environment with a completed model run.
[create_experiment()] to create list containing default and custom experimental parameters.
set.seed(42) exp <- create_experiment(log_level=0) treat_sim <- single_run(exp) print("Simulation Complete.")set.seed(42) exp <- create_experiment(log_level=0) treat_sim <- single_run(exp) print("Simulation Complete.")
Calculates mean time in system and throughput for a replication
system_kpi_for_rep_i(reps, rep_i)system_kpi_for_rep_i(reps, rep_i)
reps |
list of simmer environments |
rep_i |
replication for calculation |
data.frame