Skip to content

Commit f4d0615

Browse files
committed
feat(patients): created add_patient_generator() function which can be used to set up the exponential patient generation for each unit and patient type
1 parent 7eaa291 commit f4d0615

File tree

6 files changed

+203
-10
lines changed

6 files changed

+203
-10
lines changed

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Generated by roxygen2: do not edit by hand
22

3+
export(add_patient_generator)
34
export(create_asu_arrivals)
45
export(create_asu_los)
56
export(create_asu_routing)
@@ -15,3 +16,4 @@ importFrom(simmer,simmer)
1516
importFrom(simmer,timeout)
1617
importFrom(simmer,trajectory)
1718
importFrom(simmer,wrap)
19+
importFrom(stats,rexp)

R/add_patient_generator.R

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#' Add patient generator to Simmer environment.
2+
#'
3+
#' Creates a patient generator using an exponential inter-arrival distribution.
4+
#' The generator name is automatically constructed as \{unit\}_\{patient_type\}.
5+
#'
6+
#' @param env Simmer environment object. The simulation environment where
7+
#' generators will be added.
8+
#' @param trajectory Simmer trajectory object. Defines patient journey logic
9+
#' through the healthcare system.
10+
#' @param unit Character string specifying the care unit. Must be either "asu"
11+
#' (Acute Stroke Unit) or "rehab" (Rehabilitation Unit). Used to access correct
12+
#' parameter set and name the generator.
13+
#' @param patient_type Character string specifying patient category. Must be
14+
#' one of: "stroke", "tia", "neuro", or "other". Determines which arrival rate
15+
#' parameter is used.
16+
#' @param param Nested list containing simulation parameters. Must have
17+
#' structure `param$<unit>_arrivals$<patient_type>` containing numeric
18+
#' arrival intervals (e.g., `param$asu_arrivals$stroke = 10`).
19+
#'
20+
#' @importFrom simmer add_generator
21+
#' @importFrom stats rexp
22+
#'
23+
#' @return The modified Simmer environment with the new patient generator added.
24+
#' @export
25+
26+
add_patient_generator <- function(env, trajectory, unit, patient_type, param) {
27+
add_generator(
28+
.env = env,
29+
name_prefix = paste0(unit, "_", patient_type),
30+
trajectory = trajectory,
31+
distribution = function() {
32+
rexp(1L, 1L / param[[paste0(unit, "_arrivals")]][[patient_type]])
33+
}
34+
)
35+
}

R/model.R

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
#' may not wish to do if being set elsewhere - such as done in runner()).
77
#' Default is TRUE.
88
#'
9-
#' @importFrom simmer add_generator get_mon_arrivals get_mon_resources simmer
10-
#' @importFrom simmer timeout trajectory wrap
9+
#' @importFrom simmer get_mon_arrivals get_mon_resources simmer timeout
10+
#' @importFrom simmer trajectory wrap
1111
#'
1212
#' @return TBC
1313
#' @export
@@ -23,15 +23,25 @@ model <- function(run_number, param, set_seed = TRUE) {
2323
env <- simmer("simulation", verbose = TRUE)
2424

2525
# Define the stroke patient trajectory
26-
stroke_patient <- trajectory("stroke_patient_path") |>
27-
timeout(1)
26+
patient <- trajectory("patient_path") |>
27+
timeout(1L)
2828

29-
# Add patient generator
29+
# Add ASU and rehab direct admission patient generators
30+
for (unit in c("asu", "rehab")) {
31+
for (patient_type in names(param[[paste0(unit, "_arrivals")]])) {
32+
env <- add_patient_generator(
33+
env = env,
34+
trajectory = patient,
35+
unit = unit,
36+
patient_type = patient_type,
37+
param = param
38+
)
39+
}
40+
}
41+
42+
# Run the model
3043
env <- env |>
31-
add_generator("stroke_patient", stroke_patient, function () {
32-
rexp(n = 1L, rate = 1L / param[["asu_arrivals"]][["stroke"]])
33-
}) |>
34-
simmer::run(20) |>
44+
simmer::run(20L) |>
3545
wrap()
3646

3747
# Extract the monitored arrivals and resources information from the simmer

man/add_patient_generator.Rd

Lines changed: 34 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rmarkdown/analysis.Rmd

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
---
22
title: "analysis"
3-
output: html_document
3+
author: "Amy Heather"
4+
date: "`r Sys.Date()`"
5+
output:
6+
github_document:
7+
toc: true
8+
html_preview: false
49
---
510

611
```{r}

rmarkdown/analysis.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
analysis
2+
================
3+
Amy Heather
4+
2025-07-01
5+
6+
``` r
7+
# Load the package from the local directory
8+
devtools::load_all()
9+
```
10+
11+
## ℹ Loading simulation
12+
13+
``` r
14+
# Load the package
15+
library(simulation)
16+
```
17+
18+
``` r
19+
model(run_number = 1L, param = create_parameters(), set_seed = TRUE)
20+
```
21+
22+
## 0 | source: asu_stroke | new: asu_stroke0 | 0.906218
23+
## 0 | source: asu_tia | new: asu_tia0 | 10.9893
24+
## 0 | source: asu_neuro | new: asu_neuro0 | 0.524544
25+
## 0 | source: asu_other | new: asu_other0 | 0.447345
26+
## 0 | source: rehab_stroke | new: rehab_stroke0 | 9.5063
27+
## 0 | source: rehab_neuro | new: rehab_neuro0 | 91.7705
28+
## 0 | source: rehab_other | new: rehab_other0 | 35.1655
29+
## 0.447345 | arrival: asu_other0 | activity: Timeout | 1
30+
## 0.447345 | source: asu_other | new: asu_other1 | 2.17433
31+
## 0.524544 | arrival: asu_neuro0 | activity: Timeout | 1
32+
## 0.524544 | source: asu_neuro | new: asu_neuro1 | 3.96819
33+
## 0.906218 | arrival: asu_stroke0 | activity: Timeout | 1
34+
## 0.906218 | source: asu_stroke | new: asu_stroke1 | 1.08267
35+
## 1.08267 | arrival: asu_stroke1 | activity: Timeout | 1
36+
## 1.08267 | source: asu_stroke | new: asu_stroke2 | 2.75156
37+
## 2.17433 | arrival: asu_other1 | activity: Timeout | 1
38+
## 2.17433 | source: asu_other | new: asu_other2 | 4.61283
39+
## 2.75156 | arrival: asu_stroke2 | activity: Timeout | 1
40+
## 2.75156 | source: asu_stroke | new: asu_stroke3 | 4.23668
41+
## 3.96819 | arrival: asu_neuro1 | activity: Timeout | 1
42+
## 3.96819 | source: asu_neuro | new: asu_neuro2 | 19.8944
43+
## 4.23668 | arrival: asu_stroke3 | activity: Timeout | 1
44+
## 4.23668 | source: asu_stroke | new: asu_stroke4 | 5.50213
45+
## 4.61283 | arrival: asu_other2 | activity: Timeout | 1
46+
## 4.61283 | source: asu_other | new: asu_other3 | 7.92561
47+
## 5.50213 | arrival: asu_stroke4 | activity: Timeout | 1
48+
## 5.50213 | source: asu_stroke | new: asu_stroke5 | 7.75337
49+
## 7.75337 | arrival: asu_stroke5 | activity: Timeout | 1
50+
## 7.75337 | source: asu_stroke | new: asu_stroke6 | 8.53907
51+
## 7.92561 | arrival: asu_other3 | activity: Timeout | 1
52+
## 7.92561 | source: asu_other | new: asu_other4 | 9.00379
53+
## 8.53907 | arrival: asu_stroke6 | activity: Timeout | 1
54+
## 8.53907 | source: asu_stroke | new: asu_stroke7 | 9.24525
55+
## 9.00379 | arrival: asu_other4 | activity: Timeout | 1
56+
## 9.00379 | source: asu_other | new: asu_other5 | 16.5702
57+
## 9.24525 | arrival: asu_stroke7 | activity: Timeout | 1
58+
## 9.24525 | source: asu_stroke | new: asu_stroke8 | 10.0155
59+
## 9.5063 | arrival: rehab_stroke0 | activity: Timeout | 1
60+
## 9.5063 | source: rehab_stroke | new: rehab_stroke1 | 15.9181
61+
## 10.0155 | arrival: asu_stroke8 | activity: Timeout | 1
62+
## 10.0155 | source: asu_stroke | new: asu_stroke9 | 10.6946
63+
## 10.6946 | arrival: asu_stroke9 | activity: Timeout | 1
64+
## 10.6946 | source: asu_stroke | new: asu_stroke10 | 10.8218
65+
## 10.8218 | arrival: asu_stroke10 | activity: Timeout | 1
66+
## 10.8218 | source: asu_stroke | new: asu_stroke11 | 10.8932
67+
## 10.8932 | arrival: asu_stroke11 | activity: Timeout | 1
68+
## 10.8932 | source: asu_stroke | new: asu_stroke12 | 11.5876
69+
## 10.9893 | arrival: asu_tia0 | activity: Timeout | 1
70+
## 10.9893 | source: asu_tia | new: asu_tia1 | 47.8074
71+
## 11.5876 | arrival: asu_stroke12 | activity: Timeout | 1
72+
## 11.5876 | source: asu_stroke | new: asu_stroke13 | 12.9956
73+
## 12.9956 | arrival: asu_stroke13 | activity: Timeout | 1
74+
## 12.9956 | source: asu_stroke | new: asu_stroke14 | 14.1918
75+
## 14.1918 | arrival: asu_stroke14 | activity: Timeout | 1
76+
## 14.1918 | source: asu_stroke | new: asu_stroke15 | 15.9141
77+
## 15.9141 | arrival: asu_stroke15 | activity: Timeout | 1
78+
## 15.9141 | source: asu_stroke | new: asu_stroke16 | 15.9588
79+
## 15.9181 | arrival: rehab_stroke1 | activity: Timeout | 1
80+
## 15.9181 | source: rehab_stroke | new: rehab_stroke2 | 22.9815
81+
## 15.9588 | arrival: asu_stroke16 | activity: Timeout | 1
82+
## 15.9588 | source: asu_stroke | new: asu_stroke17 | 17.5434
83+
## 16.5702 | arrival: asu_other5 | activity: Timeout | 1
84+
## 16.5702 | source: asu_other | new: asu_other6 | 17.2215
85+
## 17.2215 | arrival: asu_other6 | activity: Timeout | 1
86+
## 17.2215 | source: asu_other | new: asu_other7 | 20.4942
87+
## 17.5434 | arrival: asu_stroke17 | activity: Timeout | 1
88+
## 17.5434 | source: asu_stroke | new: asu_stroke18 | 17.9055
89+
## 17.9055 | arrival: asu_stroke18 | activity: Timeout | 1
90+
## 17.9055 | source: asu_stroke | new: asu_stroke19 | 18.7757
91+
## 18.7757 | arrival: asu_stroke19 | activity: Timeout | 1
92+
## 18.7757 | source: asu_stroke | new: asu_stroke20 | 19.6776
93+
## 19.6776 | arrival: asu_stroke20 | activity: Timeout | 1
94+
## 19.6776 | source: asu_stroke | new: asu_stroke21 | 19.9596
95+
## 19.8944 | arrival: asu_neuro2 | activity: Timeout | 1
96+
## 19.8944 | source: asu_neuro | new: asu_neuro3 | 23.7819
97+
## 19.9596 | arrival: asu_stroke21 | activity: Timeout | 1
98+
## 19.9596 | source: asu_stroke | new: asu_stroke22 | 21.1935
99+
100+
## $arrivals
101+
## [1] name start_time end_time activity_time resource
102+
## <0 rows> (or 0-length row.names)
103+
##
104+
## $resources
105+
## [1] resource time server queue capacity queue_size system
106+
## [8] limit
107+
## <0 rows> (or 0-length row.names)

0 commit comments

Comments
 (0)