diff --git a/.gitignore b/.gitignore
index e75435c..b6d2ed9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,9 +39,6 @@ vignettes/*.pdf
# R Environment Variables
.Renviron
-# pkgdown site
-docs/
-
# translation temp files
po/*~
diff --git a/CITATION.cff b/CITATION.cff
index 88ea395..f22872a 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -20,4 +20,4 @@ abstract: >-
Reproducible analytical pipeline (RAP) for R discrete-event simulation (DES)
implementing the Stroke Capacity Planning Model from Monks et al. 2016.
version: 0.1.0
-date-released: '2025-06-30'
+date-released: '2025-07-11'
diff --git a/NEWS.md b/NEWS.md
index 749afc8..68e4b96 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -2,3 +2,11 @@
# Stroke capacity planning model: R DES RAP 0.1.0
π± First release of the R stroke model.
+
+## New features
+
+* Implementation of the stroke model in R as a package (`R/`).
+* Reproduction of paper results (`rmarkdown/analysis.Rmd`).
+* Other RMarkdown files to generate results for tests, demonstrate logging, and how parameters can be loaded from a csv (`rmarkdown/`).
+* Back, functional and unit tests (`tests/`).
+* Other features include continuous integration (tests and linting), checklists, R environment, and other metadata.
\ No newline at end of file
diff --git a/R/create_asu_trajectory.R b/R/create_asu_trajectory.R
index 55eaf19..34513b1 100644
--- a/R/create_asu_trajectory.R
+++ b/R/create_asu_trajectory.R
@@ -55,7 +55,7 @@ create_asu_trajectory <- function(env, patient_type, param) {
los_params <- switch(
dest,
esd = param[["asu_los_lnorm"]][["stroke_esd"]],
- rehab = param[["asu_los_lnorm"]][["stroke_noesd"]],
+ rehab = param[["asu_los_lnorm"]][["stroke_no_esd"]],
other = param[["asu_los_lnorm"]][["stroke_mortality"]],
stop("Stroke post-asu destination '", dest, "' invalid",
call. = FALSE)
diff --git a/R/create_rehab_trajectory.R b/R/create_rehab_trajectory.R
index aca30c5..a9751b9 100644
--- a/R/create_rehab_trajectory.R
+++ b/R/create_rehab_trajectory.R
@@ -55,7 +55,7 @@ create_rehab_trajectory <- function(env, patient_type, param) {
los_params <- switch(
dest,
esd = param[["rehab_los_lnorm"]][["stroke_esd"]],
- other = param[["rehab_los_lnorm"]][["stroke_noesd"]],
+ other = param[["rehab_los_lnorm"]][["stroke_no_esd"]],
stop("Stroke post-rehab destination '", dest, "' invalid",
call. = FALSE)
)
diff --git a/R/parameters.R b/R/parameters.R
index 9bc6dcd..5d91206 100644
--- a/R/parameters.R
+++ b/R/parameters.R
@@ -40,9 +40,9 @@ create_rehab_arrivals <- function(
#'
#' Mean and standard deviation (SD) of LOS in days in the ASU.
#'
-#' @param stroke_noesd_mean Numeric. Mean LOS for stroke patients without early
+#' @param stroke_no_esd_mean Numeric. Mean LOS for stroke patients without early
#' supported discharged (ESD).
-#' @param stroke_noesd_sd Numeric. SD LOS for stroke patients without ESD.
+#' @param stroke_no_esd_sd Numeric. SD LOS for stroke patients without ESD.
#' @param stroke_esd_mean Numeric. Mean LOS for stroke patients with ESD.
#' @param stroke_esd_sd Numeric. SD LOS for stroke patients with ESD.
#' @param stroke_mortality_mean Numeric. Mean LOS for stroke patients who pass
@@ -61,7 +61,7 @@ create_rehab_arrivals <- function(
#' @export
create_asu_los <- function(
- stroke_noesd_mean = 7.4, stroke_noesd_sd = 8.61,
+ stroke_no_esd_mean = 7.4, stroke_no_esd_sd = 8.61,
stroke_esd_mean = 4.6, stroke_esd_sd = 4.8,
stroke_mortality_mean = 7.0, stroke_mortality_sd = 8.7,
tia_mean = 1.8, tia_sd = 2.3,
@@ -69,7 +69,7 @@ create_asu_los <- function(
other_mean = 3.8, other_sd = 5.2
) {
list(
- stroke_noesd = list(mean = stroke_noesd_mean, sd = stroke_noesd_sd),
+ stroke_no_esd = list(mean = stroke_no_esd_mean, sd = stroke_no_esd_sd),
stroke_esd = list(mean = stroke_esd_mean, sd = stroke_esd_sd),
stroke_mortality = list(mean = stroke_mortality_mean,
sd = stroke_mortality_sd),
@@ -81,9 +81,9 @@ create_asu_los <- function(
#' Rehabilitation unit length of stay (LOS) distributions (days).
#'
-#' @param stroke_noesd_mean Numeric. Mean LOS for stroke patients without early
+#' @param stroke_no_esd_mean Numeric. Mean LOS for stroke patients without early
#' supported discharged (ESD).
-#' @param stroke_noesd_sd Numeric. SD LOS for stroke patients without ESD.
+#' @param stroke_no_esd_sd Numeric. SD LOS for stroke patients without ESD.
#' @param stroke_esd_mean Numeric. Mean LOS for stroke patients with ESD.
#' @param stroke_esd_sd Numeric. SD LOS for stroke patients with ESD.
#' @param tia_mean Numeric. Mean LOS for transient ischemic attack (TIA)
@@ -98,14 +98,14 @@ create_asu_los <- function(
#' @export
create_rehab_los <- function(
- stroke_noesd_mean = 28.4, stroke_noesd_sd = 27.2,
+ stroke_no_esd_mean = 28.4, stroke_no_esd_sd = 27.2,
stroke_esd_mean = 30.3, stroke_esd_sd = 23.1,
tia_mean = 18.7, tia_sd = 23.5,
neuro_mean = 27.6, neuro_sd = 28.4,
other_mean = 16.1, other_sd = 14.1
) {
list(
- stroke_noesd = list(mean = stroke_noesd_mean, sd = stroke_noesd_sd),
+ stroke_no_esd = list(mean = stroke_no_esd_mean, sd = stroke_no_esd_sd),
stroke_esd = list(mean = stroke_esd_mean, sd = stroke_esd_sd),
tia = list(mean = tia_mean, sd = tia_sd),
neuro = list(mean = neuro_mean, sd = neuro_sd),
diff --git a/README.md b/README.md
index 232e38f..2d81aab 100644
--- a/README.md
+++ b/README.md
@@ -56,16 +56,45 @@ renv::snapshot()
The simulation code is in the `R/` folder as a local package. There are files executing the model and analysing the results in `rmarkdown/`.
-To run the model with base parameters once or with replications:
+**Install the local package:**
```{.r}
-# TODO
+devtools::install() # Needed if running in parallel
+devtools::load_all() # Sufficient if running sequentially
+
+library(simulation)
+```
+
+**Run a single simulation:**
+
+```{.r}
+param <- create_parameters(number_of_runs = 1L)
+single_results <- runner(param = param)
```
-Example altering the model parameters:
+**Run multiple replications:**
```{.r}
-# TODO
+param <- create_parameters(number_of_runs = 5L)
+single_results <- runner(param = param)
+```
+
+**Run all analyses (from command line):**
+
+```{.r}
+bash run_rmarkdown.sh
+```
+
+**Run tests:**
+
+```{.r}
+devtools::test()
+```
+
+**Lint code:**
+
+```{.r}
+lintr::lint_dir()
```
### Generating the results from the article
@@ -87,23 +116,27 @@ To generate these, simply execute `rmarkdown/analysis.Rmd`.
Original:
+
+
From this repository:
-**TODO**
+
**Figure 3**
Original:
+
+
From this repository:
-**TODO**
+
## Run time and machine specification
-The run time for this analysis (`notebooks/analysis.Rm`) is **TODO** seconds. This was on an Intel Core i7-12700H, 32GB RAM, Ubuntu 24.04.1.
+The run time for this analysis (`notebooks/analysis.Rmd`) is **1m 38s** seconds. This was on an Intel Core i7-12700H, 32GB RAM, Ubuntu 24.04.1.
The other notebooks generate results for tests and illustrate other functionality (e.g. importing parameters from csv, running with logs), and these just take a second or two.
diff --git a/docs/article/article_monks_etal_2016.pdf b/docs/article/article_monks_etal_2016.pdf
new file mode 100644
index 0000000..e56be17
Binary files /dev/null and b/docs/article/article_monks_etal_2016.pdf differ
diff --git a/docs/article/fig1.png b/docs/article/fig1.png
new file mode 100644
index 0000000..d747c96
Binary files /dev/null and b/docs/article/fig1.png differ
diff --git a/docs/article/fig2.png b/docs/article/fig2.png
new file mode 100644
index 0000000..2006a7a
Binary files /dev/null and b/docs/article/fig2.png differ
diff --git a/docs/article/fig3.png b/docs/article/fig3.png
new file mode 100644
index 0000000..da60437
Binary files /dev/null and b/docs/article/fig3.png differ
diff --git a/docs/article/supplementary_monks_etal_2016.docx b/docs/article/supplementary_monks_etal_2016.docx
new file mode 100644
index 0000000..f0cce05
Binary files /dev/null and b/docs/article/supplementary_monks_etal_2016.docx differ
diff --git a/docs/article/supplementary_monks_etal_2016.pdf b/docs/article/supplementary_monks_etal_2016.pdf
new file mode 100644
index 0000000..05d4d1f
Binary files /dev/null and b/docs/article/supplementary_monks_etal_2016.pdf differ
diff --git a/docs/heather_2025.md b/docs/heather_2025.md
new file mode 100644
index 0000000..bc127ed
--- /dev/null
+++ b/docs/heather_2025.md
@@ -0,0 +1,38 @@
+# Reproducibility recommendations from Heather et al. 2025
+
+As part of the project STARS (Sharing Tools and Artefacts for Reproducible Simulations), a series of computational reproducibility assessments were conducted by Heather et al. 2025 (**TODO: add DOI of pre-print**). From these, several recommendations were shared to support reproducibility of healthcare discrete-event simulation (DES) models. These are copied below. Those marked with a star (β) were identified as having the greatest impact in Heather et al. 2025.
+
+## Recommendations to support reproduction
+
+| Recommendation | Completion | Further details |
+| - | - | - |
+| **Set-up** |
+| Share code with an open licence (β) | β
| `LICENSE` and `LICENSE.md` |
+| Link publication to a specific version of the code | β
| - |
+| List dependencies and versions | β
| `renv.lock` and `DESCRIPTION` |
+| **Running the model** |
+| Provide code for all scenarios and sensitivity analyses (β) | β
| `analysis.Rmd` |
+| Ensure model parameters are correct (β) | β
| - |
+| Control randomness | β
| - |
+| **Outputs** |
+| Include code to calculate all required model outputs (β) | β
| - |
+| Include code to generate the tables, figures, and other reported results (β) | β
| `analysis.Rmd` |
+
+## Recommendations to support troubleshooting and reuse
+
+| Recommendation | Completion | Further details |
+| - | - | - |
+| **Design** |
+| Separate model code from applications | β
| - |
+| Avoid hard-coded parameters | β
| - |
+| Minimise code duplication | β
| - |
+| **Clarity** |
+| Comment sufficiently | β
| - |
+| Ensure clarity and consistency in the model results tables | β
| - |
+| Include run instructions | β
| - |
+| State run times and machine specifications | β
| In `README.md` and `.Rmd` files. |
+| **Functionality** |
+| Optimise model run time | β
| Provides option for parallel processing. |
+| Save outputs to a file | β
| - |
+| Avoid excessive output files | β
| - |
+| Address large file sizes | N/A | - |
\ No newline at end of file
diff --git a/docs/nhs_rap.md b/docs/nhs_rap.md
new file mode 100644
index 0000000..dab1f14
--- /dev/null
+++ b/docs/nhs_rap.md
@@ -0,0 +1,50 @@
+# 'Levels of RAP' Maturity Framework
+
+The following framework has been directly copied from the RAP Community of Practice repository/website: [NHS RAP Levels of RAP Framework](https://nhsdigital.github.io/rap-community-of-practice/introduction_to_RAP/levels_of_RAP/).
+
+This framework is maintained by the NHS RAP Community of Practice and is Β© 2024 Crown Copyright (NHS England), shared by them under the terms of the [Open Government 3.0 licence](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/).
+
+The specific version of the framework copied below is that from commit [2549256](https://github.com/NHSDigital/rap-community-of-practice/commit/2549256498886d6d7ea4cdb736e2a2864c8bb461) (9th September 2024).
+
+## π₯ Baseline
+
+RAP fundamentals offering resilience against future change.
+
+| Criteria | Completion | Further details |
+| - | - | - |
+| Data produced by code in an open-source language (e.g., Python, R, SQL). | β
| R |
+| Code is version controlled (see [Git basics](https://nhsdigital.github.io/rap-community-of-practice/training_resources/git/introduction-to-git/) and [using Git collaboratively](https://nhsdigital.github.io/rap-community-of-practice/training_resources/git/using-git-collaboratively/) guides). | β
| [GitHub](https://github.com/pythonhealthdatascience/rdesrap_stroke) |
+| Repository includes a README.md file (or equivalent) that clearly details steps a user must follow to reproduce the code (use [NHS Open Source Policy section on Readmes](https://github.com/nhsx/open-source-policy/blob/main/open-source-policy.md#b-readmes) as a guide). | β
| - |
+| Code has been [peer reviewed](https://nhsdigital.github.io/rap-community-of-practice/implementing_RAP/workflow/code-review/). | β
| Peer reviewed by Tom Monks |
+| Code is [published in the open](https://nhsdigital.github.io/rap-community-of-practice/implementing_RAP/publishing_code/how-to-publish-your-code-in-the-open/) and linked to & from accompanying publication (if relevant). | β
| - |
+
+## π₯ Silver
+
+Implementing best practice by following good analytical and software engineering standards.
+
+Meeting all of the above requirements, plus:https://github.com/pythonhealthdatascience/rdesrap_mms
+
+| Criteria | Completion | Further details |
+| - | - | - |
+| Outputs are produced by code with minimal manual intervention. | β
| - |
+| Code is well-documented including user guidance, explanation of code structure & methodology and [docstrings](https://nhsdigital.github.io/rap-community-of-practice/training_resources/python/python-functions/#documentation) for functions. | β
| - |
+| Code is well-organised following [standard directory format](https://nhsdigital.github.io/rap-community-of-practice/training_resources/python/project-structure-and-packaging/). | β
| - |
+| [Reusable functions](https://nhsdigital.github.io/rap-community-of-practice/training_resources/python/python-functions/) and/or classes are used where appropriate. | β
| - |
+| Code adheres to agreed coding standards (e.g PEP8, [style guide for Pyspark](https://nhsdigital.github.io/rap-community-of-practice/training_resources/pyspark/pyspark-style-guide/)). | β
| - |
+| Pipeline includes a testing framework ([unit tests](https://nhsdigital.github.io/rap-community-of-practice/training_resources/python/unit-testing/), [back tests](https://nhsdigital.github.io/rap-community-of-practice/training_resources/python/backtesting/)). | β
| `tests/` contains unit, functional and back tests. |
+| Repository includes dependency information (e.g. [requirements.txt](https://pip.pypa.io/en/stable/user_guide/#requirements-files), [PipFile](https://github.com/pypa/pipfile/blob/main/README.rst), [environment.yml](https://nhsdigital.github.io/rap-community-of-practice/training_resources/python/virtual-environments/conda/)). | β
| `renv` |
+| [Logs](https://nhsdigital.github.io/rap-community-of-practice/training_resources/python/logging-and-error-handling/) are automatically recorded by the pipeline to ensure outputs are as expected. | β
| - |
+| Data is handled and output in a [Tidy data format](https://medium.com/@kimrodrikwa/untidy-data-a90b6e3ebe4c). | β
| Meets the requirements of tidy data (each variable forms a column, each observation forms a row, each type of observational unit forms a table). |
+
+## π₯ Gold
+
+Analysis as a product to further elevate your analytical work and enhance its reusability to the public.
+
+Meeting all of the above requirements, plus:
+
+| Criteria | Completion | Further details |
+| - | - | - |
+| Code is fully [packaged](https://packaging.python.org/en/latest/). | β
| - |
+| Repository automatically runs tests etc. via CI/CD or a different integration/deployment tool e.g. [GitHub Actions](https://docs.github.com/en/actions). | β
| `.github/workflows/R-CMD-check.yaml` |
+| Process runs based on event-based triggers (e.g., new data in database) or on a schedule. | N/A | - |
+| Changes to the RAP are clearly signposted. E.g. a changelog in the package, releases etc. (See gov.uk info on [Semantic Versioning](https://github.com/alphagov/govuk-frontend/blob/main/docs/contributing/versioning.md)). | β
| `NEWS.md` and GitHub releases. |
\ No newline at end of file
diff --git a/docs/stress_des.md b/docs/stress_des.md
new file mode 100644
index 0000000..65fe577
--- /dev/null
+++ b/docs/stress_des.md
@@ -0,0 +1,44 @@
+# Strengthening the Reporting of Empirical Simulation Studies (STRESS)
+
+**Discrete-event simulation guidelines (STRESS-DES) Version 1.0**
+
+This checklist describes the study:
+
+> Monks T, Worthington D, Allen M, Pitt M, Stein K, James MA. A modelling tool for capacity planning in acute and community stroke services. BMC Health Serv Res. 2016 Sep 29;16(1):530. doi: [10.1186/s12913-016-1789-4](https://doi.org/10.1186/s12913-016-1789-4). PMID: 27688152; PMCID: PMC5043535.
+
+Answers to this checklist, and the diagram used, are copied and/or adapted from [llm_simpy/notebooks/03_stroke/00_stress/](https://github.com/pythonhealthdatascience/llm_simpy/tree/main/notebooks/03_stroke/00_stress), which is shared under an MIT licence by:
+
+> Monks, T., Harper, A., & Heather, A. (2025). Unlocking the Potential of Past Research: Using Generative AI to Reconstruct Healthcare Simulation Models. GitHub. https://github.com/pythonhealthdatascience/llm_simpy.
+
+| **Item** | **Description** |
+| - | - |
+| **Objectives** |
+| **1.1 Purpose of the model**
Explain the background and objectives for the model | The simulation model provides capacity planning tools for acute stroke and rehabilitation units across a shared service that cares for Stroke, TIA, Complex Neurology and other types of neurological dependency patients. It guides users on the likelihood that a given capacity will cause admission delays. |
+| **1.2 Model outputs**
Define all quantitative performance measures that are reported, using equations where necessary. Specify how and when they are calculated during the model run along with how any measures of error such as confidence intervals are calculated. | At the end of a model run the following is calculated:
γ» The probability of delay - p(delay) - in admission to an Acute Stroke Unit by bed numbers.
γ» The probability of delay - p(delay) - in admission to a Rehabilitation Unit by bed numbers.
γ» The reciprocal of p(delay) for both ASU and Rehab. Interpreted as 1 in every n patients is delayed.
γ» The occupancy distribution of the Acute Stroke Unit.
γ» The occupancy distribution of the Rehabilitation Unit
The probability of delay is calculated as follows: `P(N=n)/P(<=n)` |
+| **1.3 Experimentation aims**
If the model has been used for experimentation, state the objectives that it was used to investigate.
(A) Scenario based analysis β Provide a name and description for each scenario, providing a rationale for the choice of scenarios and ensure that item 2.3 (below) is completed.
(B) Design of experiments β Provide details of the overall design of the experiments with reference to performance measures and their parameters (provide further details in data below).
(C) Simulation Optimisation β (if appropriate) Provide full details of what is to be optimised, the parameters that were included and the algorithm(s) that was be used. Where possible provide a citation of the algorithm(s). | This is an infinite server model. A single scenario is run, given set of arrival and length of stay parameters, to produce a distribution of outputs. |
+| **Logic** |
+| **2.1 Base model overview diagram**
Describe the base model using appropriate diagrams and description. This could include one or more process flow, activity cycle or equivalent diagrams sufficient to describe the model to readers. Avoid complicated diagrams in the main text. The goal is to describe the breadth and depth of the model with respect to the system being studied. |  |
+| **2.2 Base model logic**
Give details of the base model logic. Give additional model logic details sufficient to communicate to the reader how the model works. | The model allows users to specify a population of stroke, transient ischaemic attack (TIA; or mini-stroke), complex neurological, and other patient types that use acute and rehabilitation services. The patient classes have their own external inter-arrival distributions to acute and rehabilitation services, transfer probabilities between services and length of stay distributions (where first sub division occurs to model ESD versus non-ESD patients). The model takes an infinite capacity approach to capacity planning and estimates the probability of delay. A warm-up period and multiple replications are employed. The ESD modelling is not documented in the article we therefore chose to simplify the design and focus on the acute stroke and rehabilitation units; although we aimed for model setup to be simple to extend for ESD capacity modelling. |
+| **2.3 Scenario logic**
Give details of the logical difference between the base case model and scenarios (if any). This could be incorporated as text or where differences are substantial could be incorporated in the same manner as 2.2. | Only a single scenario is included in this recreation experiment. To recreate the original paperβs increased demand scenarios the inter-arrival times could be increased in the `Experiment` class. |
+| **2.4 Algorithms**
Provide further detail on any algorithms in the model that (for example) mimic complex or manual processes in the real world (i.e. scheduling of arrivals/ appointments/ operations/ maintenance, operation of a conveyor system, machine breakdowns, etc.). Sufficient detail should be included (or referred to in other published work) for the algorithms to be reproducible. Pseudo-code may be used to describe an algorithm. | There are no algorithms used in this model. |
+| **2.5.1 Components - entities**
Give details of all entities within the simulation including a description of their role in the model and a description of all their attributes. | γ» Stroke
γ» Transient Ischemic Attack (TIA - minor strokes with rapidly resolving symptoms)
γ» Complex Neurological
γ» Other (including medical outliers) |
+| **2.5.2 Components - activities**
Describe the activities that entities engage in within the model. Provide details of entity routing into and out of the activity. | ASU + rehab treatment activities:
γ» Stroke patients who are eligible for Early Supported Discharge
γ» Stroke patients who are **NOT** eligible for Early Supported Discharge
γ» TIA
γ» Other |
+| **2.5.3 Components - resources**
List all the resources included within the model and which activities make use of them. | γ» ASU beds (infinite)
γ» Rehab beds (infinite) |
+| **2.5.4 Components - queues**
Give details of the assumed queuing discipline used in the model (e.g. First in First Out, Last in First Out, prioritisation, etc.). Where one or more queues have a different discipline from the rest, provide a list of queues, indicating the queuing discipline used for each. If reneging, balking or jockeying occur, etc., provide details of the rules. Detail any delays or capacity constraints on the queues. | γ» None |
+| **2.5.5 Components - entry/exit points**
Give details of the model boundaries i.e. all arrival and exit points of entities. Detail the arrival mechanism (e.g. βthinningβ to mimic a non-homogenous Poisson process or balking) | γ» Each patient class has an ASU arrival process with its own distribution and parameters.
γ» A proportion of ASU patients exit the model after acute treatment is complete.
γ» Stroke, Complex Neurological and Other patients have an additional external Rehab arrival process with its own distribution and parameters.
γ» All rehab patients exit the model when rehab is completed. |
+| **Data** |
+| **3.1 Data sources**
List and detail all data sources. Sources may include:
β’ Interviews with stakeholders,
β’ Samples of routinely collected data,
β’ Prospectively collected samples for the purpose of the simulation study,
β’ Public domain data published in either academic or organisational literature. Provide, where possible, the link and DOI to the data or reference to published literature.
All data source descriptions should include details of the sample size, sample date ranges and use within the study. | All data is sourced from the 2016 publication in the Health Services Research: Monks T, Worthington D, Allen M, Pitt M, Stein K, James MA. A modelling tool for capacity planning in acute and community stroke services. BMC Health Serv Res. 2016 Sep 29;16(1):530. doi: 10.1186/s12913-016-1789-4. PMID: 27688152; PMCID: PMC5043535.
In [Monks et al. (2016)](http://doi.org/10.1186/s12913-016-1789-4) they state: "*The model was constructed using anonymised administrative data collected routinely by the healthcare provider in the acute and community settings.*" |
+| **3.2 Pre-processing**
Provide details of any data manipulation that has taken place before its use in the simulation, e.g. interpolation to account for missing data or the removal of outliers. | No additional pre-processing of data was undertaken. This was conducted in the original study.
In [Monks et al. (2016)](http://doi.org/10.1186/s12913-016-1789-4) they state: "*All patients had a recorded primary diagnosis using ICD-10 coding. These codes were grouped into a simpler coding scheme of stroke (ischemic or haemorrhagic), TIA, complex neurological and other. The βotherβ category represents medical patients who are displaced into the stroke units due to capacity constraints elsewhere in the hospital.*" |
+| **3.3 Input parameters**
List all input variables in the model. Provide a description of their use and include parameter values. For stochastic inputs provide details of any continuous, discrete or empirical distributions used along with all associated parameters. Give details of all time dependent parameters and correlation.
Clearly state:
β’ Base case data
β’ Data use in experimentation, where different from the base case.
β’ Where optimisation or design of experiments has been used, state the range of values that parameters can take.
β’ Where theoretical distributions are used, state how these were selected and prioritised above other candidate distributions. | All sampling distributions are reported in the original paper. We did not make any additional assumptions.
**Arrivals and length of stay parameters**
β’ ASU Arrivals: Stroke - Exponential(1.2 days)
β’ ASU Arrivals: TIA - Exponential(9.3 days)
β’ ASU Arrivals: Complex Neuro - Exponential(3.6 days)
β’ ASU Arrivals: Other - Exponential(3.2 days)
β’ Rehab Arrivals: Stroke - Exponential(21.8 days)
β’ Rehab Arrivals: Complex Neuro - Exponential(31.7 days)
β’ Rehab Arrivals: Other - Exponential(28.6 days)
β’ ASU Length of Stay: Stroke No ESD - LogNormal(mean=7.4, sd=8.61)
β’ ASU Length of Stay: Stroke ESD - LogNormal(mean=4.6, sd=4.8)
β’ ASU Length of Stay: TIA - LogNormal(mean=1.8, sd=2.3)
β’ ASU Length of Stay: Complex Neuro - LogNormal(mean=4.0, sd=5.0)
β’ ASU Length of Stay: Other - LogNormal(mean=3.8, sd=5.2)
β’ Rehab Length of Stay: Stroke No ESD - LogNormal(mean=28.4, sd=27.2)
β’ Rehab Length of Stay: Stroke ESD - LogNormal(mean=30.3, sd=23.1)
β’ Rehab Length of Stay: TIA - LogNormal(mean=18.7, sd=23.5)
β’ Rehab Length of Stay: Complex Neuro - LogNormal(mean=27.6, sd=28.4)
β’ Rehab Length of Stay: Other - LogNormal(mean=16.1, sd=14.1)
**Patient routing out of ASU**
A discrete distribution was used for each patient type with the following probabilities:
β’ Rehab - stroke 24%, TIA 1%, complex neuro 11%, other 5%.
β’ ESD - stroke 13%, TIA 1%, complex neuro 5%, other 10%
β’ Other - stroke 63%, TIA 98%, complex neuro 84%, other 85%
**Patient routing out of rehab**
A discrete distribution was used for each patient type with the following probabilities:
β’ ESD stroke 40%, TIA 0%, complex neuro 9%, other 13%
β’ Other - stroke 60%, TIA 100%, complex neuro 91%, other 88%|
+| **3.4 Assumptions**
Where data or knowledge of the real system is unavailable what assumptions are included in the model? This might include parameter values, distributions or routing logic within the model. | β’ Monks et al. report that the model can be used to report results for ESD probability of delay and capacity.
β’ No data are given for Length of stay in this service. Therefore we simplified the model to use ESD as an exit point. |
+| **Experimentation** |
+| **4.1 Initialisation**
Report if the system modelled is terminating or non-terminating. State if a warm-up period has been used, its length and the analysis method used to select it. For terminating systems state the stopping condition.
State what if any initial model conditions have been included, e.g., pre-loaded queues and activities. Report whether initialisation of these variables is deterministic or stochastic. | The model is a non-terminating system. It has a default warm-up of 3 years (365 days * 3). |
+| **4.2 Run length**
Detail the run length of the simulation model and time units. | The time units used in the model are days and a results collection period of 5 years (365 days * 5). |
+| **4.3 Estimation approach**
State the method used to account for the stochasticity: For example, two common methods are multiple replications or batch means. Where multiple replications have been used, state the number of replications and for batch means, indicate the batch length and whether the batch means procedure is standard, spaced or overlapping. For both procedures provide a justification for the methods used and the number of replications/size of batches. | Multiple independent replications are employed to account for lack of independence. Common random numbers are employed between scenarios. A total of 150 replications are run for each experiment, but this number can be varied. |
+| **Implementation** |
+| **5.1 Software or programming language**
State the operating system and version and build number.
State the name, version and build number of commercial or open source DES software that the model is implemented in.
State the name and version of general-purpose programming languages used (e.g. Python 3.5).
Where frameworks and libraries have been used provide all details including version numbers. | The simulation model was developed using R 4.4.1 and simmer 4.4.7. A renv environment is provided to manage versions on a local machine. |
+| **5.2 Random sampling**
State the algorithm used to generate random samples in the software/programming language used e.g. Mersenne Twister.
If common random numbers are used, state how seeds (or random number streams) are distributed among sampling processes. | Random sampling in `model()` uses R's base random number generator, which uses the Mersenne Twister algorithm, and `set.seed(run_number)`. When called with `runner()`, it is instead managed by the future ecosystem, which uses `future.seed` to ensure independent, reproducible random number streams for each parallel task. |
+| **5.3 Model execution**
State the event processing mechanism used e.g. three phase, event, activity, process interaction.
*Note that in some commercial software the event processing mechanism may not be published. In these cases authors should adhere to item 5.1 software recommendations.*
State all priority rules included if entities/activities compete for resources.
If the model is parallel, distributed and/or use grid or cloud computing, etc., state and preferably reference the technology used. For parallel and distributed simulations the time management algorithms used. If the HLA is used then state the version of the standard, which run-time infrastructure (and version), and any supporting documents (FOMs, etc.) | `simmer` implements a process based simulation worldview. |
+| **5.4 System specification**
State the model run time and specification of hardware used. This is particularly important for large scale models that require substantial computing power. For parallel, distributed and/or use grid or cloud computing, etc. state the details of all systems used in the implementation (processors, network, etc.) | Intel Core i7-12700H with 32GB RAM running Ubuntu 24.04.1 Linux. |
+| **Code access** |
+| **6.1 Computer model sharing statement**
Describe how someone could obtain the model described in the paper, the simulation software and any other associated software (or hardware) needed to reproduce the results. Provide, where possible, the link and DOIs to these. | Code is provided in https://github.com/pythonhealthdatascience/rdesrap_stroke. |
diff --git a/inputs/data_dictionary.md b/inputs/data_dictionary.md
new file mode 100644
index 0000000..47e8d9a
--- /dev/null
+++ b/inputs/data_dictionary.md
@@ -0,0 +1,9 @@
+# Data dictionary for `parameters.csv`
+
+| Column | Data type | Description | Possible values |
+| - | - | - | - |
+| unit | str | Hospital unit | `asu`: Acute Stroke Unit
`rehab`: Rehabilitation Unit (post-acute recovery care) |
+| parameter | str | Type of operational metric | `iat`: Inter-arrival time (time between patient admissions)
`los`: Length of stay (duration from admission to discharge)
`routing`: Transition probability between care pathways |
+| type | str | Patient classification or care transition path | **For `iat`/`los`:**
`stroke`: Stroke patients
`stroke_esd`: Stroke patients transferred to Early Supported Discharge
`stroke_no_esd`: Stroke patients not transferred to Early Supported Discharge
`tia`: Transient Ischemic Attack patients
`neuro`: Complex neurological patients
`other`: Other patient types
**For `routing`:**
`[diagnosis]_rehab`: Probability of transferring to rehabilitation unit
`[diagnosis]_esd`: Probability of Early Supported Discharge
`[diagnosis]_other`: Probability of other discharge pathways |
+| mean | float | **For `iat`:** Mean days between admissions
**For `los`:** Mean days in unit
**For `routing`:** Probability (0-1 scale) | - |
+| sd | float | Standard deviation of the mean | - |
\ No newline at end of file
diff --git a/inputs/parameters.csv b/inputs/parameters.csv
new file mode 100644
index 0000000..43d1a5c
--- /dev/null
+++ b/inputs/parameters.csv
@@ -0,0 +1,38 @@
+unit,parameter,type,mean,sd
+asu,iat,stroke,1.2,NA
+asu,iat,tia,9.3,NA
+asu,iat,neuro,3.6,NA
+asu,iat,other,3.2,NA
+rehab,iat,stroke,21.8,NA
+rehab,iat,neuro,31.7,NA
+rehab,iat,other,28.6,NA
+asu,los,stroke_no_esd,7.4,8.61
+asu,los,stroke_esd,4.6,4.8
+asu,los,tia,1.8,2.3
+asu,los,neuro,4,5
+asu,los,other,3.8,5.2
+rehab,los,stroke_no_esd,28.4,27.2
+rehab,los,stroke_esd,30.3,2un3.1
+rehab,los,tia,18.7,23.5
+rehab,los,neuro,27.6,28.4
+rehab,los,other,16.1,14.1
+asu,routing,stroke_rehab,0.24,NA
+asu,routing,stroke_esd,0.13,NA
+asu,routing,stroke_other,0.63,NA
+asu,routing,tia_rehab,0.01,NA
+asu,routing,tia_esd,0.01,NA
+asu,routing,tia_other,0.98,NA
+asu,routing,neuro_rehab,0.11,NA
+asu,routing,neuro_esd,0.05,NA
+asu,routing,neuro_other,0.84,NA
+asu,routing,other_rehab,0.05,NA
+asu,routing,other_esd,0.1,NA
+asu,routing,other_other,0.85,NA
+rehab,routing,stroke_esd,0.4,NA
+rehab,routing,stroke_other,0.6,NA
+rehab,routing,tia_esd,0,NA
+rehab,routing,tia_other,1,NA
+rehab,routing,neuro_esd,0.09,NA
+rehab,routing,neuro_other,0.91,NA
+rehab,routing,other_esd,0.13,NA
+rehab,routing,other_other,0.88,NA
diff --git a/man/create_asu_los.Rd b/man/create_asu_los.Rd
index ac609ad..eadce7e 100644
--- a/man/create_asu_los.Rd
+++ b/man/create_asu_los.Rd
@@ -5,8 +5,8 @@
\title{Acute Stroke Unit (ASU) length of stay (LOS) distributions (days).}
\usage{
create_asu_los(
- stroke_noesd_mean = 7.4,
- stroke_noesd_sd = 8.61,
+ stroke_no_esd_mean = 7.4,
+ stroke_no_esd_sd = 8.61,
stroke_esd_mean = 4.6,
stroke_esd_sd = 4.8,
stroke_mortality_mean = 7,
@@ -20,10 +20,10 @@ create_asu_los(
)
}
\arguments{
-\item{stroke_noesd_mean}{Numeric. Mean LOS for stroke patients without early
+\item{stroke_no_esd_mean}{Numeric. Mean LOS for stroke patients without early
supported discharged (ESD).}
-\item{stroke_noesd_sd}{Numeric. SD LOS for stroke patients without ESD.}
+\item{stroke_no_esd_sd}{Numeric. SD LOS for stroke patients without ESD.}
\item{stroke_esd_mean}{Numeric. Mean LOS for stroke patients with ESD.}
diff --git a/man/create_rehab_los.Rd b/man/create_rehab_los.Rd
index 8e509f4..13d3553 100644
--- a/man/create_rehab_los.Rd
+++ b/man/create_rehab_los.Rd
@@ -5,8 +5,8 @@
\title{Rehabilitation unit length of stay (LOS) distributions (days).}
\usage{
create_rehab_los(
- stroke_noesd_mean = 28.4,
- stroke_noesd_sd = 27.2,
+ stroke_no_esd_mean = 28.4,
+ stroke_no_esd_sd = 27.2,
stroke_esd_mean = 30.3,
stroke_esd_sd = 23.1,
tia_mean = 18.7,
@@ -18,10 +18,10 @@ create_rehab_los(
)
}
\arguments{
-\item{stroke_noesd_mean}{Numeric. Mean LOS for stroke patients without early
+\item{stroke_no_esd_mean}{Numeric. Mean LOS for stroke patients without early
supported discharged (ESD).}
-\item{stroke_noesd_sd}{Numeric. SD LOS for stroke patients without ESD.}
+\item{stroke_no_esd_sd}{Numeric. SD LOS for stroke patients without ESD.}
\item{stroke_esd_mean}{Numeric. Mean LOS for stroke patients with ESD.}
diff --git a/outputs/log_example.log b/outputs/log_example.log
index a00f104..8e5efdb 100644
--- a/outputs/log_example.log
+++ b/outputs/log_example.log
@@ -1,8 +1,8 @@
Parameters:
asu_arrivals=list(stroke = 1.2, tia = 9.3, neuro = 3.6, other = 3.2);
rehab_arrivals=list(stroke = 3, neuro = 31.7, other = 28.6);
- asu_los=list(stroke_noesd = list(mean = 7.4, sd = 8.61), stroke_esd = list(mean = 4.6, sd = 4.8), stroke_mortality = list(mean = 7, sd = 8.7), tia = list(mean = 1.8, sd = 2.3), neuro = list(mean = 4, sd = 5), other = list(mean = 3.8, sd = 5.2));
- rehab_los=list(stroke_noesd = list(mean = 28.4, sd = 27.2), stroke_esd = list(mean = 30.3, sd = 23.1), tia = list(mean = 18.7, sd = 23.5), neuro = list(mean = 27.6, sd = 28.4), other = list(mean = 16.1, sd = 14.1));
+ asu_los=list(stroke_no_esd = list(mean = 7.4, sd = 8.61), stroke_esd = list(mean = 4.6, sd = 4.8), stroke_mortality = list(mean = 7, sd = 8.7), tia = list(mean = 1.8, sd = 2.3), neuro = list(mean = 4, sd = 5), other = list(mean = 3.8, sd = 5.2));
+ rehab_los=list(stroke_no_esd = list(mean = 28.4, sd = 27.2), stroke_esd = list(mean = 30.3, sd = 23.1), tia = list(mean = 18.7, sd = 23.5), neuro = list(mean = 27.6, sd = 28.4), other = list(mean = 16.1, sd = 14.1));
asu_routing=list(stroke = list(rehab = 0.24, esd = 0.13, other = 0.63), tia = list(rehab = 0.01, esd = 0.01, other = 0.98), neuro = list(rehab = 0.11, esd = 0.05, other = 0.84), other = list(rehab = 0.05, esd = 0.1, other = 0.85));
rehab_routing=list(stroke = list(esd = 0.4, other = 0.6), tia = list(esd = 0, other = 1), neuro = list(esd = 0.09, other = 0.91), other = list(esd = 0.13, other = 0.88));
warm_up_period=3;
@@ -14,8 +14,8 @@ asu_arrivals=list(stroke = 1.2, tia = 9.3, neuro = 3.6, other = 3.2);
log_to_file=TRUE;
file_path=../outputs/log_example.log;
verbose=TRUE;
- asu_los_lnorm=list(stroke_noesd = list(meanlog = 1.57347219029677, sdlog = 0.925211121759084), stroke_esd = list(meanlog = 1.15775021244827, sdlog = 0.858261138636461), stroke_mortality = list(meanlog = 1.47890496960638, sdlog = 0.966442113578391), tia = list(meanlog = 0.103778649052444, sdlog = 0.983878057331979), neuro = list(meanlog = 0.915802688887627, sdlog = 0.970042960112864), other = list(meanlog = 0.807396441784017, sdlog = 1.02723378541433));
- rehab_los_lnorm=list(stroke_noesd = list(meanlog = 3.02093582638726, sdlog = 0.806787851643665), stroke_esd = list(meanlog = 3.18205014379696, sdlog = 0.676901128257839), tia = list(meanlog = 2.45477304821951, sdlog = 0.973396605337238), neuro = list(meanlog = 2.95675141458562, sdlog = 0.849781569743057), other = list(meanlog = 2.49418211833932, sdlog = 0.754502688730926))
+ asu_los_lnorm=list(stroke_no_esd = list(meanlog = 1.57347219029677, sdlog = 0.925211121759084), stroke_esd = list(meanlog = 1.15775021244827, sdlog = 0.858261138636461), stroke_mortality = list(meanlog = 1.47890496960638, sdlog = 0.966442113578391), tia = list(meanlog = 0.103778649052444, sdlog = 0.983878057331979), neuro = list(meanlog = 0.915802688887627, sdlog = 0.970042960112864), other = list(meanlog = 0.807396441784017, sdlog = 1.02723378541433));
+ rehab_los_lnorm=list(stroke_no_esd = list(meanlog = 3.02093582638726, sdlog = 0.806787851643665), stroke_esd = list(meanlog = 3.18205014379696, sdlog = 0.676901128257839), tia = list(meanlog = 2.45477304821951, sdlog = 0.973396605337238), neuro = list(meanlog = 2.95675141458562, sdlog = 0.849781569743057), other = list(meanlog = 2.49418211833932, sdlog = 0.754502688730926))
Log:
0.865903: asu_other0: πΆ Arrived at ASU
0.865903: asu_other0: π― Planned ASU -> 3 (other)
diff --git a/rmarkdown/analysis.md b/rmarkdown/analysis.md
index 7213fd1..b9d414b 100644
--- a/rmarkdown/analysis.md
+++ b/rmarkdown/analysis.md
@@ -70,11 +70,12 @@ devtools::install(upgrade = "never")
## checking DESCRIPTION meta-information ... β checking DESCRIPTION meta-information
## β checking for LF line-endings in source and make files and shell scripts
## β checking for empty or unneeded directories
+ ## Removed empty directory βsimulation/tests/testthat/_snapsβ
## Omitted βLazyDataβ from DESCRIPTION
## β building βsimulation_0.1.0.tar.gzβ
##
## Running /opt/R/4.4.1/lib/R/bin/R CMD INSTALL \
- ## /tmp/RtmpH3Tbtm/simulation_0.1.0.tar.gz --install-tests
+ ## /tmp/Rtmpz9aafi/simulation_0.1.0.tar.gz --install-tests
## * installing to library β/home/amy/.cache/R/renv/library/rdesrap_stroke-34041c45/linux-ubuntu-noble/R-4.4/x86_64-pc-linux-gnuβ
## * installing *source* package βsimulationβ ...
## ** using staged installation
@@ -1048,4 +1049,4 @@ seconds <- as.integer(runtime %% 60L)
cat(sprintf("Notebook run time: %dm %ds", minutes, seconds))
```
- ## Notebook run time: 1m 38s
+ ## Notebook run time: 2m 33s
diff --git a/rmarkdown/generate_exp_results.Rmd b/rmarkdown/generate_exp_results.Rmd
index a65cabb..639ef7b 100644
--- a/rmarkdown/generate_exp_results.Rmd
+++ b/rmarkdown/generate_exp_results.Rmd
@@ -27,7 +27,6 @@ Load required packages.
```{r setup}
# nolint start: undesirable_function_linter.
library(dplyr)
-library(simulation)
# nolint end
```
diff --git a/rmarkdown/generate_exp_results.md b/rmarkdown/generate_exp_results.md
index 1a34e5f..1562012 100644
--- a/rmarkdown/generate_exp_results.md
+++ b/rmarkdown/generate_exp_results.md
@@ -1,7 +1,7 @@
Generate expected results
================
Amy Heather
-2025-07-10
+2025-07-11
- [Set-up](#set-up)
- [Base case](#base-case)
@@ -54,7 +54,6 @@ library(dplyr)
## intersect, setdiff, setequal, union
``` r
-library(simulation)
# nolint end
```
@@ -103,11 +102,11 @@ print(param)
##
##
## $asu_los
- ## $asu_los$stroke_noesd
- ## $asu_los$stroke_noesd$mean
+ ## $asu_los$stroke_no_esd
+ ## $asu_los$stroke_no_esd$mean
## [1] 7.4
##
- ## $asu_los$stroke_noesd$sd
+ ## $asu_los$stroke_no_esd$sd
## [1] 8.61
##
##
@@ -153,11 +152,11 @@ print(param)
##
##
## $rehab_los
- ## $rehab_los$stroke_noesd
- ## $rehab_los$stroke_noesd$mean
+ ## $rehab_los$stroke_no_esd
+ ## $rehab_los$stroke_no_esd$mean
## [1] 28.4
##
- ## $rehab_los$stroke_noesd$sd
+ ## $rehab_los$stroke_no_esd$sd
## [1] 27.2
##
##
@@ -389,4 +388,4 @@ seconds <- as.integer(runtime %% 60L)
cat(sprintf("Notebook run time: %dm %ds", minutes, seconds))
```
- ## Notebook run time: 0m 1s
+ ## Notebook run time: 0m 3s
diff --git a/rmarkdown/logs.md b/rmarkdown/logs.md
index db7c92f..4eb708e 100644
--- a/rmarkdown/logs.md
+++ b/rmarkdown/logs.md
@@ -1,7 +1,7 @@
Logs
================
Amy Heather
-2025-07-10
+2025-07-11
- [Set up](#set-up)
- [Simulation run with logs printed to the
@@ -63,55 +63,55 @@ param <- create_parameters(
verbose_run <- runner(param = param)
```
- ## [1] "Parameters:"
- ## [2] "asu_arrivals=list(stroke = 1.2, tia = 9.3, neuro = 3.6, other = 3.2);\n rehab_arrivals=list(stroke = 3, neuro = 31.7, other = 28.6);\n asu_los=list(stroke_noesd = list(mean = 7.4, sd = 8.61), stroke_esd = list(mean = 4.6, sd = 4.8), stroke_mortality = list(mean = 7, sd = 8.7), tia = list(mean = 1.8, sd = 2.3), neuro = list(mean = 4, sd = 5), other = list(mean = 3.8, sd = 5.2));\n rehab_los=list(stroke_noesd = list(mean = 28.4, sd = 27.2), stroke_esd = list(mean = 30.3, sd = 23.1), tia = list(mean = 18.7, sd = 23.5), neuro = list(mean = 27.6, sd = 28.4), other = list(mean = 16.1, sd = 14.1));\n asu_routing=list(stroke = list(rehab = 0.24, esd = 0.13, other = 0.63), tia = list(rehab = 0.01, esd = 0.01, other = 0.98), neuro = list(rehab = 0.11, esd = 0.05, other = 0.84), other = list(rehab = 0.05, esd = 0.1, other = 0.85));\n rehab_routing=list(stroke = list(esd = 0.4, other = 0.6), tia = list(esd = 0, other = 1), neuro = list(esd = 0.09, other = 0.91), other = list(esd = 0.13, other = 0.88));\n warm_up_period=3;\n data_collection_period=5;\n number_of_runs=1;\n scenario_name=NULL;\n cores=1;\n log_to_console=TRUE;\n log_to_file=TRUE;\n file_path=../outputs/log_example.log;\n verbose=TRUE;\n asu_los_lnorm=list(stroke_noesd = list(meanlog = 1.57347219029677, sdlog = 0.925211121759084), stroke_esd = list(meanlog = 1.15775021244827, sdlog = 0.858261138636461), stroke_mortality = list(meanlog = 1.47890496960638, sdlog = 0.966442113578391), tia = list(meanlog = 0.103778649052444, sdlog = 0.983878057331979), neuro = list(meanlog = 0.915802688887627, sdlog = 0.970042960112864), other = list(meanlog = 0.807396441784017, sdlog = 1.02723378541433));\n rehab_los_lnorm=list(stroke_noesd = list(meanlog = 3.02093582638726, sdlog = 0.806787851643665), stroke_esd = list(meanlog = 3.18205014379696, sdlog = 0.676901128257839), tia = list(meanlog = 2.45477304821951, sdlog = 0.973396605337238), neuro = list(meanlog = 2.95675141458562, sdlog = 0.849781569743057), other = list(meanlog = 2.49418211833932, sdlog = 0.754502688730926))"
- ## [3] "Log:"
- ## [4] "0.865903: asu_other0: πΆ Arrived at ASU"
- ## [5] "0.865903: asu_other0: π― Planned ASU -> 3 (other)"
- ## [6] "0.865903: asu_other0: β³ ASU length of stay: 5.571"
- ## [7] "1.28404: asu_tia0: πΆ Arrived at ASU"
- ## [8] "1.28404: asu_tia0: π― Planned ASU -> 3 (other)"
- ## [9] "1.28404: asu_tia0: β³ ASU length of stay: 1.887"
- ## [10] "2.38768: asu_stroke0: πΆ Arrived at ASU"
- ## [11] "2.38768: asu_stroke0: π― Planned ASU -> 3 (other)"
- ## [12] "2.38768: asu_stroke0: β³ ASU length of stay: 8.198"
- ## [13] "3.17069: asu_tia0: π ASU stay completed"
- ## [14] "3.97542: asu_other1: πΆ Arrived at ASU"
- ## [15] "3.97542: asu_other1: π― Planned ASU -> 3 (other)"
- ## [16] "3.97542: asu_other1: β³ ASU length of stay: 0.209"
- ## [17] "4.16715: asu_tia1: πΆ Arrived at ASU"
- ## [18] "4.16715: asu_tia1: π― Planned ASU -> 3 (other)"
- ## [19] "4.16715: asu_tia1: β³ ASU length of stay: 0.2"
- ## [20] "4.18468: asu_other1: π ASU stay completed"
- ## [21] "4.19181: rehab_stroke0: πΆ Arrived at rehab"
- ## [22] "4.19181: rehab_stroke0: π― Planned rehab -> 1 (esd)"
- ## [23] "4.19181: rehab_stroke0: β³ Rehab length of stay: 10.714"
- ## [24] "4.36704: asu_tia1: π ASU stay completed"
- ## [25] "4.70094: asu_stroke1: πΆ Arrived at ASU"
- ## [26] "4.70094: asu_stroke1: π― Planned ASU -> 3 (other)"
- ## [27] "4.70094: asu_stroke1: β³ ASU length of stay: 1.704"
- ## [28] "5.77621: asu_neuro0: πΆ Arrived at ASU"
- ## [29] "5.77621: asu_neuro0: π― Planned ASU -> 3 (other)"
- ## [30] "5.77621: asu_neuro0: β³ ASU length of stay: 2.623"
- ## [31] "5.82361: asu_stroke2: πΆ Arrived at ASU"
- ## [32] "5.82361: asu_stroke2: π― Planned ASU -> 1 (rehab)"
- ## [33] "5.82361: asu_stroke2: β³ ASU length of stay: 68.121"
- ## [34] "5.97769: asu_other2: πΆ Arrived at ASU"
- ## [35] "5.97769: asu_other2: π― Planned ASU -> 3 (other)"
- ## [36] "5.97769: asu_other2: β³ ASU length of stay: 3.719"
- ## [37] "6.40479: asu_stroke1: π ASU stay completed"
- ## [38] "6.43669: asu_other0: π ASU stay completed"
- ## [39] "6.61333: asu_stroke3: πΆ Arrived at ASU"
- ## [40] "6.61333: asu_stroke3: π― Planned ASU -> 3 (other)"
- ## [41] "6.61333: asu_stroke3: β³ ASU length of stay: 2.321"
- ## [42] "7.12946: asu_stroke4: πΆ Arrived at ASU"
- ## [43] "7.12946: asu_stroke4: π― Planned ASU -> 3 (other)"
- ## [44] "7.12946: asu_stroke4: β³ ASU length of stay: 12.365"
- ## [45] "7.29875: rehab_stroke1: πΆ Arrived at rehab"
- ## [46] "7.29875: rehab_stroke1: π― Planned rehab -> 2 (other)"
- ## [47] "7.29875: rehab_stroke1: β³ Rehab length of stay: 34.847"
- ## [48] "7.77172: asu_other3: πΆ Arrived at ASU"
- ## [49] "7.77172: asu_other3: π― Planned ASU -> 3 (other)"
+ ## [1] "Parameters:"
+ ## [2] "asu_arrivals=list(stroke = 1.2, tia = 9.3, neuro = 3.6, other = 3.2);\n rehab_arrivals=list(stroke = 3, neuro = 31.7, other = 28.6);\n asu_los=list(stroke_no_esd = list(mean = 7.4, sd = 8.61), stroke_esd = list(mean = 4.6, sd = 4.8), stroke_mortality = list(mean = 7, sd = 8.7), tia = list(mean = 1.8, sd = 2.3), neuro = list(mean = 4, sd = 5), other = list(mean = 3.8, sd = 5.2));\n rehab_los=list(stroke_no_esd = list(mean = 28.4, sd = 27.2), stroke_esd = list(mean = 30.3, sd = 23.1), tia = list(mean = 18.7, sd = 23.5), neuro = list(mean = 27.6, sd = 28.4), other = list(mean = 16.1, sd = 14.1));\n asu_routing=list(stroke = list(rehab = 0.24, esd = 0.13, other = 0.63), tia = list(rehab = 0.01, esd = 0.01, other = 0.98), neuro = list(rehab = 0.11, esd = 0.05, other = 0.84), other = list(rehab = 0.05, esd = 0.1, other = 0.85));\n rehab_routing=list(stroke = list(esd = 0.4, other = 0.6), tia = list(esd = 0, other = 1), neuro = list(esd = 0.09, other = 0.91), other = list(esd = 0.13, other = 0.88));\n warm_up_period=3;\n data_collection_period=5;\n number_of_runs=1;\n scenario_name=NULL;\n cores=1;\n log_to_console=TRUE;\n log_to_file=TRUE;\n file_path=../outputs/log_example.log;\n verbose=TRUE;\n asu_los_lnorm=list(stroke_no_esd = list(meanlog = 1.57347219029677, sdlog = 0.925211121759084), stroke_esd = list(meanlog = 1.15775021244827, sdlog = 0.858261138636461), stroke_mortality = list(meanlog = 1.47890496960638, sdlog = 0.966442113578391), tia = list(meanlog = 0.103778649052444, sdlog = 0.983878057331979), neuro = list(meanlog = 0.915802688887627, sdlog = 0.970042960112864), other = list(meanlog = 0.807396441784017, sdlog = 1.02723378541433));\n rehab_los_lnorm=list(stroke_no_esd = list(meanlog = 3.02093582638726, sdlog = 0.806787851643665), stroke_esd = list(meanlog = 3.18205014379696, sdlog = 0.676901128257839), tia = list(meanlog = 2.45477304821951, sdlog = 0.973396605337238), neuro = list(meanlog = 2.95675141458562, sdlog = 0.849781569743057), other = list(meanlog = 2.49418211833932, sdlog = 0.754502688730926))"
+ ## [3] "Log:"
+ ## [4] "0.865903: asu_other0: πΆ Arrived at ASU"
+ ## [5] "0.865903: asu_other0: π― Planned ASU -> 3 (other)"
+ ## [6] "0.865903: asu_other0: β³ ASU length of stay: 5.571"
+ ## [7] "1.28404: asu_tia0: πΆ Arrived at ASU"
+ ## [8] "1.28404: asu_tia0: π― Planned ASU -> 3 (other)"
+ ## [9] "1.28404: asu_tia0: β³ ASU length of stay: 1.887"
+ ## [10] "2.38768: asu_stroke0: πΆ Arrived at ASU"
+ ## [11] "2.38768: asu_stroke0: π― Planned ASU -> 3 (other)"
+ ## [12] "2.38768: asu_stroke0: β³ ASU length of stay: 8.198"
+ ## [13] "3.17069: asu_tia0: π ASU stay completed"
+ ## [14] "3.97542: asu_other1: πΆ Arrived at ASU"
+ ## [15] "3.97542: asu_other1: π― Planned ASU -> 3 (other)"
+ ## [16] "3.97542: asu_other1: β³ ASU length of stay: 0.209"
+ ## [17] "4.16715: asu_tia1: πΆ Arrived at ASU"
+ ## [18] "4.16715: asu_tia1: π― Planned ASU -> 3 (other)"
+ ## [19] "4.16715: asu_tia1: β³ ASU length of stay: 0.2"
+ ## [20] "4.18468: asu_other1: π ASU stay completed"
+ ## [21] "4.19181: rehab_stroke0: πΆ Arrived at rehab"
+ ## [22] "4.19181: rehab_stroke0: π― Planned rehab -> 1 (esd)"
+ ## [23] "4.19181: rehab_stroke0: β³ Rehab length of stay: 10.714"
+ ## [24] "4.36704: asu_tia1: π ASU stay completed"
+ ## [25] "4.70094: asu_stroke1: πΆ Arrived at ASU"
+ ## [26] "4.70094: asu_stroke1: π― Planned ASU -> 3 (other)"
+ ## [27] "4.70094: asu_stroke1: β³ ASU length of stay: 1.704"
+ ## [28] "5.77621: asu_neuro0: πΆ Arrived at ASU"
+ ## [29] "5.77621: asu_neuro0: π― Planned ASU -> 3 (other)"
+ ## [30] "5.77621: asu_neuro0: β³ ASU length of stay: 2.623"
+ ## [31] "5.82361: asu_stroke2: πΆ Arrived at ASU"
+ ## [32] "5.82361: asu_stroke2: π― Planned ASU -> 1 (rehab)"
+ ## [33] "5.82361: asu_stroke2: β³ ASU length of stay: 68.121"
+ ## [34] "5.97769: asu_other2: πΆ Arrived at ASU"
+ ## [35] "5.97769: asu_other2: π― Planned ASU -> 3 (other)"
+ ## [36] "5.97769: asu_other2: β³ ASU length of stay: 3.719"
+ ## [37] "6.40479: asu_stroke1: π ASU stay completed"
+ ## [38] "6.43669: asu_other0: π ASU stay completed"
+ ## [39] "6.61333: asu_stroke3: πΆ Arrived at ASU"
+ ## [40] "6.61333: asu_stroke3: π― Planned ASU -> 3 (other)"
+ ## [41] "6.61333: asu_stroke3: β³ ASU length of stay: 2.321"
+ ## [42] "7.12946: asu_stroke4: πΆ Arrived at ASU"
+ ## [43] "7.12946: asu_stroke4: π― Planned ASU -> 3 (other)"
+ ## [44] "7.12946: asu_stroke4: β³ ASU length of stay: 12.365"
+ ## [45] "7.29875: rehab_stroke1: πΆ Arrived at rehab"
+ ## [46] "7.29875: rehab_stroke1: π― Planned rehab -> 2 (other)"
+ ## [47] "7.29875: rehab_stroke1: β³ Rehab length of stay: 34.847"
+ ## [48] "7.77172: asu_other3: πΆ Arrived at ASU"
+ ## [49] "7.77172: asu_other3: π― Planned ASU -> 3 (other)"
## [50] "7.77172: asu_other3: β³ ASU length of stay: 0.513"
If we import the log file, weβll see it contains the same output:
@@ -121,69 +121,69 @@ log_contents <- readLines(log_file)
print(log_contents, sep = "\n")
```
- ## [1] "Parameters:"
- ## [2] "asu_arrivals=list(stroke = 1.2, tia = 9.3, neuro = 3.6, other = 3.2);"
- ## [3] " rehab_arrivals=list(stroke = 3, neuro = 31.7, other = 28.6);"
- ## [4] " asu_los=list(stroke_noesd = list(mean = 7.4, sd = 8.61), stroke_esd = list(mean = 4.6, sd = 4.8), stroke_mortality = list(mean = 7, sd = 8.7), tia = list(mean = 1.8, sd = 2.3), neuro = list(mean = 4, sd = 5), other = list(mean = 3.8, sd = 5.2));"
- ## [5] " rehab_los=list(stroke_noesd = list(mean = 28.4, sd = 27.2), stroke_esd = list(mean = 30.3, sd = 23.1), tia = list(mean = 18.7, sd = 23.5), neuro = list(mean = 27.6, sd = 28.4), other = list(mean = 16.1, sd = 14.1));"
- ## [6] " asu_routing=list(stroke = list(rehab = 0.24, esd = 0.13, other = 0.63), tia = list(rehab = 0.01, esd = 0.01, other = 0.98), neuro = list(rehab = 0.11, esd = 0.05, other = 0.84), other = list(rehab = 0.05, esd = 0.1, other = 0.85));"
- ## [7] " rehab_routing=list(stroke = list(esd = 0.4, other = 0.6), tia = list(esd = 0, other = 1), neuro = list(esd = 0.09, other = 0.91), other = list(esd = 0.13, other = 0.88));"
- ## [8] " warm_up_period=3;"
- ## [9] " data_collection_period=5;"
- ## [10] " number_of_runs=1;"
- ## [11] " scenario_name=NULL;"
- ## [12] " cores=1;"
- ## [13] " log_to_console=TRUE;"
- ## [14] " log_to_file=TRUE;"
- ## [15] " file_path=../outputs/log_example.log;"
- ## [16] " verbose=TRUE;"
- ## [17] " asu_los_lnorm=list(stroke_noesd = list(meanlog = 1.57347219029677, sdlog = 0.925211121759084), stroke_esd = list(meanlog = 1.15775021244827, sdlog = 0.858261138636461), stroke_mortality = list(meanlog = 1.47890496960638, sdlog = 0.966442113578391), tia = list(meanlog = 0.103778649052444, sdlog = 0.983878057331979), neuro = list(meanlog = 0.915802688887627, sdlog = 0.970042960112864), other = list(meanlog = 0.807396441784017, sdlog = 1.02723378541433));"
- ## [18] " rehab_los_lnorm=list(stroke_noesd = list(meanlog = 3.02093582638726, sdlog = 0.806787851643665), stroke_esd = list(meanlog = 3.18205014379696, sdlog = 0.676901128257839), tia = list(meanlog = 2.45477304821951, sdlog = 0.973396605337238), neuro = list(meanlog = 2.95675141458562, sdlog = 0.849781569743057), other = list(meanlog = 2.49418211833932, sdlog = 0.754502688730926))"
- ## [19] "Log:"
- ## [20] "0.865903: asu_other0: πΆ Arrived at ASU"
- ## [21] "0.865903: asu_other0: π― Planned ASU -> 3 (other)"
- ## [22] "0.865903: asu_other0: β³ ASU length of stay: 5.571"
- ## [23] "1.28404: asu_tia0: πΆ Arrived at ASU"
- ## [24] "1.28404: asu_tia0: π― Planned ASU -> 3 (other)"
- ## [25] "1.28404: asu_tia0: β³ ASU length of stay: 1.887"
- ## [26] "2.38768: asu_stroke0: πΆ Arrived at ASU"
- ## [27] "2.38768: asu_stroke0: π― Planned ASU -> 3 (other)"
- ## [28] "2.38768: asu_stroke0: β³ ASU length of stay: 8.198"
- ## [29] "3.17069: asu_tia0: π ASU stay completed"
- ## [30] "3.97542: asu_other1: πΆ Arrived at ASU"
- ## [31] "3.97542: asu_other1: π― Planned ASU -> 3 (other)"
- ## [32] "3.97542: asu_other1: β³ ASU length of stay: 0.209"
- ## [33] "4.16715: asu_tia1: πΆ Arrived at ASU"
- ## [34] "4.16715: asu_tia1: π― Planned ASU -> 3 (other)"
- ## [35] "4.16715: asu_tia1: β³ ASU length of stay: 0.2"
- ## [36] "4.18468: asu_other1: π ASU stay completed"
- ## [37] "4.19181: rehab_stroke0: πΆ Arrived at rehab"
- ## [38] "4.19181: rehab_stroke0: π― Planned rehab -> 1 (esd)"
- ## [39] "4.19181: rehab_stroke0: β³ Rehab length of stay: 10.714"
- ## [40] "4.36704: asu_tia1: π ASU stay completed"
- ## [41] "4.70094: asu_stroke1: πΆ Arrived at ASU"
- ## [42] "4.70094: asu_stroke1: π― Planned ASU -> 3 (other)"
- ## [43] "4.70094: asu_stroke1: β³ ASU length of stay: 1.704"
- ## [44] "5.77621: asu_neuro0: πΆ Arrived at ASU"
- ## [45] "5.77621: asu_neuro0: π― Planned ASU -> 3 (other)"
- ## [46] "5.77621: asu_neuro0: β³ ASU length of stay: 2.623"
- ## [47] "5.82361: asu_stroke2: πΆ Arrived at ASU"
- ## [48] "5.82361: asu_stroke2: π― Planned ASU -> 1 (rehab)"
- ## [49] "5.82361: asu_stroke2: β³ ASU length of stay: 68.121"
- ## [50] "5.97769: asu_other2: πΆ Arrived at ASU"
- ## [51] "5.97769: asu_other2: π― Planned ASU -> 3 (other)"
- ## [52] "5.97769: asu_other2: β³ ASU length of stay: 3.719"
- ## [53] "6.40479: asu_stroke1: π ASU stay completed"
- ## [54] "6.43669: asu_other0: π ASU stay completed"
- ## [55] "6.61333: asu_stroke3: πΆ Arrived at ASU"
- ## [56] "6.61333: asu_stroke3: π― Planned ASU -> 3 (other)"
- ## [57] "6.61333: asu_stroke3: β³ ASU length of stay: 2.321"
- ## [58] "7.12946: asu_stroke4: πΆ Arrived at ASU"
- ## [59] "7.12946: asu_stroke4: π― Planned ASU -> 3 (other)"
- ## [60] "7.12946: asu_stroke4: β³ ASU length of stay: 12.365"
- ## [61] "7.29875: rehab_stroke1: πΆ Arrived at rehab"
- ## [62] "7.29875: rehab_stroke1: π― Planned rehab -> 2 (other)"
- ## [63] "7.29875: rehab_stroke1: β³ Rehab length of stay: 34.847"
- ## [64] "7.77172: asu_other3: πΆ Arrived at ASU"
- ## [65] "7.77172: asu_other3: π― Planned ASU -> 3 (other)"
+ ## [1] "Parameters:"
+ ## [2] "asu_arrivals=list(stroke = 1.2, tia = 9.3, neuro = 3.6, other = 3.2);"
+ ## [3] " rehab_arrivals=list(stroke = 3, neuro = 31.7, other = 28.6);"
+ ## [4] " asu_los=list(stroke_no_esd = list(mean = 7.4, sd = 8.61), stroke_esd = list(mean = 4.6, sd = 4.8), stroke_mortality = list(mean = 7, sd = 8.7), tia = list(mean = 1.8, sd = 2.3), neuro = list(mean = 4, sd = 5), other = list(mean = 3.8, sd = 5.2));"
+ ## [5] " rehab_los=list(stroke_no_esd = list(mean = 28.4, sd = 27.2), stroke_esd = list(mean = 30.3, sd = 23.1), tia = list(mean = 18.7, sd = 23.5), neuro = list(mean = 27.6, sd = 28.4), other = list(mean = 16.1, sd = 14.1));"
+ ## [6] " asu_routing=list(stroke = list(rehab = 0.24, esd = 0.13, other = 0.63), tia = list(rehab = 0.01, esd = 0.01, other = 0.98), neuro = list(rehab = 0.11, esd = 0.05, other = 0.84), other = list(rehab = 0.05, esd = 0.1, other = 0.85));"
+ ## [7] " rehab_routing=list(stroke = list(esd = 0.4, other = 0.6), tia = list(esd = 0, other = 1), neuro = list(esd = 0.09, other = 0.91), other = list(esd = 0.13, other = 0.88));"
+ ## [8] " warm_up_period=3;"
+ ## [9] " data_collection_period=5;"
+ ## [10] " number_of_runs=1;"
+ ## [11] " scenario_name=NULL;"
+ ## [12] " cores=1;"
+ ## [13] " log_to_console=TRUE;"
+ ## [14] " log_to_file=TRUE;"
+ ## [15] " file_path=../outputs/log_example.log;"
+ ## [16] " verbose=TRUE;"
+ ## [17] " asu_los_lnorm=list(stroke_no_esd = list(meanlog = 1.57347219029677, sdlog = 0.925211121759084), stroke_esd = list(meanlog = 1.15775021244827, sdlog = 0.858261138636461), stroke_mortality = list(meanlog = 1.47890496960638, sdlog = 0.966442113578391), tia = list(meanlog = 0.103778649052444, sdlog = 0.983878057331979), neuro = list(meanlog = 0.915802688887627, sdlog = 0.970042960112864), other = list(meanlog = 0.807396441784017, sdlog = 1.02723378541433));"
+ ## [18] " rehab_los_lnorm=list(stroke_no_esd = list(meanlog = 3.02093582638726, sdlog = 0.806787851643665), stroke_esd = list(meanlog = 3.18205014379696, sdlog = 0.676901128257839), tia = list(meanlog = 2.45477304821951, sdlog = 0.973396605337238), neuro = list(meanlog = 2.95675141458562, sdlog = 0.849781569743057), other = list(meanlog = 2.49418211833932, sdlog = 0.754502688730926))"
+ ## [19] "Log:"
+ ## [20] "0.865903: asu_other0: πΆ Arrived at ASU"
+ ## [21] "0.865903: asu_other0: π― Planned ASU -> 3 (other)"
+ ## [22] "0.865903: asu_other0: β³ ASU length of stay: 5.571"
+ ## [23] "1.28404: asu_tia0: πΆ Arrived at ASU"
+ ## [24] "1.28404: asu_tia0: π― Planned ASU -> 3 (other)"
+ ## [25] "1.28404: asu_tia0: β³ ASU length of stay: 1.887"
+ ## [26] "2.38768: asu_stroke0: πΆ Arrived at ASU"
+ ## [27] "2.38768: asu_stroke0: π― Planned ASU -> 3 (other)"
+ ## [28] "2.38768: asu_stroke0: β³ ASU length of stay: 8.198"
+ ## [29] "3.17069: asu_tia0: π ASU stay completed"
+ ## [30] "3.97542: asu_other1: πΆ Arrived at ASU"
+ ## [31] "3.97542: asu_other1: π― Planned ASU -> 3 (other)"
+ ## [32] "3.97542: asu_other1: β³ ASU length of stay: 0.209"
+ ## [33] "4.16715: asu_tia1: πΆ Arrived at ASU"
+ ## [34] "4.16715: asu_tia1: π― Planned ASU -> 3 (other)"
+ ## [35] "4.16715: asu_tia1: β³ ASU length of stay: 0.2"
+ ## [36] "4.18468: asu_other1: π ASU stay completed"
+ ## [37] "4.19181: rehab_stroke0: πΆ Arrived at rehab"
+ ## [38] "4.19181: rehab_stroke0: π― Planned rehab -> 1 (esd)"
+ ## [39] "4.19181: rehab_stroke0: β³ Rehab length of stay: 10.714"
+ ## [40] "4.36704: asu_tia1: π ASU stay completed"
+ ## [41] "4.70094: asu_stroke1: πΆ Arrived at ASU"
+ ## [42] "4.70094: asu_stroke1: π― Planned ASU -> 3 (other)"
+ ## [43] "4.70094: asu_stroke1: β³ ASU length of stay: 1.704"
+ ## [44] "5.77621: asu_neuro0: πΆ Arrived at ASU"
+ ## [45] "5.77621: asu_neuro0: π― Planned ASU -> 3 (other)"
+ ## [46] "5.77621: asu_neuro0: β³ ASU length of stay: 2.623"
+ ## [47] "5.82361: asu_stroke2: πΆ Arrived at ASU"
+ ## [48] "5.82361: asu_stroke2: π― Planned ASU -> 1 (rehab)"
+ ## [49] "5.82361: asu_stroke2: β³ ASU length of stay: 68.121"
+ ## [50] "5.97769: asu_other2: πΆ Arrived at ASU"
+ ## [51] "5.97769: asu_other2: π― Planned ASU -> 3 (other)"
+ ## [52] "5.97769: asu_other2: β³ ASU length of stay: 3.719"
+ ## [53] "6.40479: asu_stroke1: π ASU stay completed"
+ ## [54] "6.43669: asu_other0: π ASU stay completed"
+ ## [55] "6.61333: asu_stroke3: πΆ Arrived at ASU"
+ ## [56] "6.61333: asu_stroke3: π― Planned ASU -> 3 (other)"
+ ## [57] "6.61333: asu_stroke3: β³ ASU length of stay: 2.321"
+ ## [58] "7.12946: asu_stroke4: πΆ Arrived at ASU"
+ ## [59] "7.12946: asu_stroke4: π― Planned ASU -> 3 (other)"
+ ## [60] "7.12946: asu_stroke4: β³ ASU length of stay: 12.365"
+ ## [61] "7.29875: rehab_stroke1: πΆ Arrived at rehab"
+ ## [62] "7.29875: rehab_stroke1: π― Planned rehab -> 2 (other)"
+ ## [63] "7.29875: rehab_stroke1: β³ Rehab length of stay: 34.847"
+ ## [64] "7.77172: asu_other3: πΆ Arrived at ASU"
+ ## [65] "7.77172: asu_other3: π― Planned ASU -> 3 (other)"
## [66] "7.77172: asu_other3: β³ ASU length of stay: 0.513"
diff --git a/rmarkdown/parameters_csv.Rmd b/rmarkdown/parameters_csv.Rmd
new file mode 100644
index 0000000..2c3dd50
--- /dev/null
+++ b/rmarkdown/parameters_csv.Rmd
@@ -0,0 +1,137 @@
+---
+title: "Using parameters from csv"
+author: "Amy Heather"
+date: "`r Sys.Date()`"
+output:
+ github_document:
+ toc: true
+html_preview: false
+---
+
+## Set-up
+
+Install the latest version of the local simulation package. If running sequentially, `devtools::load_all()` is sufficient. If running in parallel, you must use `devtools::install()`.
+
+```{r}
+devtools::load_all()
+```
+
+```{r}
+start_time <- Sys.time()
+```
+
+## Creating parameter class
+
+We can set up classes based on CSV, replacing the default inputs with those from the csv.
+
+If you were only planning to use parameters from CSV, then you could remove the default inputs from the classes in `parameters.R` altogether.
+
+We use the parameter function to process values from the CSV, ensuring that all required parameter names are present and that no unexpected arguments are included. This approach leverages the function's built-in validation to catch any issues with argument names or types. If the parameter classes themselves have validation, those checks will also be performed when the function is called.
+```{r}
+#' Use parameter function to create parameter list using values from dataframe.
+#'
+#' @param data Dataframe with columns "unit", "parameter", "type", "mean" and
+#' "sd".
+#' @param unit Unit name to filter by ("asu" or "rehab").
+#' @param parameter Parameter name to filter by ("iat", "los" or "routing").
+#' @param param_function Function to run
+#'
+#' @return Named list of parameters
+
+init_param_class <- function(data, unit, parameter, param_function) {
+
+ # Filter data to specified unit and parameter
+ df_subset <- data[data[["unit"]] == unit &
+ data[["parameter"]] == parameter, ]
+
+ # Create named list of parameter values.
+ # If all SD values are missing, use only means and name by 'type'.
+ # Otherwise, include both mean and sd for each type, with names like
+ # 'type_mean' and 'type_sd'.
+ if (all(is.na(df_subset$sd))) {
+ param_list <- as.list(setNames(df_subset$mean, df_subset$type))
+ } else {
+ param_list <- list()
+ for (i in seq_len(nrow(df_subset))) {
+ df_row <- df_subset[i, ]
+ param_list[[paste0(df_row$type, "_mean")]] <- df_row$mean
+ param_list[[paste0(df_row$type, "_sd")]] <- df_row$sd
+ }
+ }
+
+ # Run parameter function using list
+ do.call(param_function, param_list)
+}
+```
+
+```{r}
+#' Generate named_list with create_parameters() using values loaded from a CSV
+#' file.
+#'
+#' @param csv_path Path to csv file containing the parameters. Should have
+#' columns "unit", "parameter", "type", "mean" and "sd". Missing values should
+#' be marked as "NA".
+#'
+#' @return Named list generated by create_parameters()
+
+setup_param_from_csv <- function(csv_path) {
+ # Load parameter data from CSV, treating "NA" as missing values
+ param_data <- read.csv(csv_path, na.strings = "NA")
+
+ # Specify mappings of create_parameters() arguments to their corresponding
+ # units, parameter types and parameter classes
+ param_specs <- list(
+ list(name = "asu_arrivals",
+ unit = "asu",
+ parameter = "iat",
+ param_function = create_asu_arrivals),
+ list(name = "rehab_arrivals",
+ unit = "rehab",
+ parameter = "iat",
+ param_function = create_rehab_arrivals),
+ list(name = "asu_los",
+ unit = "asu",
+ parameter = "los",
+ param_function = create_asu_los),
+ list(name = "rehab_los",
+ unit = "rehab",
+ parameter = "los",
+ param_function = create_rehab_los),
+ list(name = "asu_routing",
+ unit = "asu",
+ parameter = "routing",
+ param_function = create_asu_routing),
+ list(name = "rehab_routing",
+ unit = "rehab",
+ parameter = "routing",
+ param_function = create_rehab_routing)
+ )
+ param_kwargs <- list()
+ for (spec in param_specs) {
+ param_kwargs[[spec$name]] <- init_param_class(
+ data = param_data, unit = spec$unit, parameter = spec$parameter,
+ param_function = spec$param_function
+ )
+ }
+
+ do.call(create_parameters, param_kwargs)
+}
+```
+
+```{r}
+setup_param_from_csv(file.path("..", "inputs", "parameters.csv"))
+```
+
+## Calculate run time
+
+```{r end_timer}
+# Get run time in seconds
+end_time <- Sys.time()
+runtime <- as.numeric(end_time - start_time, units = "secs")
+
+# Display converted to minutes and seconds
+minutes <- as.integer(runtime / 60L)
+seconds <- as.integer(runtime %% 60L)
+cat(sprintf("Notebook run time: %dm %ds", minutes, seconds))
+```
+
diff --git a/rmarkdown/parameters_csv.md b/rmarkdown/parameters_csv.md
new file mode 100644
index 0000000..8d3c35d
--- /dev/null
+++ b/rmarkdown/parameters_csv.md
@@ -0,0 +1,366 @@
+Using parameters from csv
+================
+Amy Heather
+2025-07-11
+
+## Set-up
+
+Install the latest version of the local simulation package. If running
+sequentially, `devtools::load_all()` is sufficient. If running in
+parallel, you must use `devtools::install()`.
+
+``` r
+devtools::load_all()
+```
+
+ ## βΉ Loading simulation
+
+``` r
+start_time <- Sys.time()
+```
+
+## Creating parameter class
+
+We can set up classes based on CSV, replacing the default inputs with
+those from the csv.
+
+If you were only planning to use parameters from CSV, then you could
+remove the default inputs from the classes in `parameters.R` altogether.
+
+We use the parameter function to process values from the CSV, ensuring
+that all required parameter names are present and that no unexpected
+arguments are included. This approach leverages the functionβs built-in
+validation to catch any issues with argument names or types. If the
+parameter classes themselves have validation, those checks will also be
+performed when the function is called.
+
+``` r
+#' Use parameter function to create parameter list using values from dataframe.
+#'
+#' @param data Dataframe with columns "unit", "parameter", "type", "mean" and
+#' "sd".
+#' @param unit Unit name to filter by ("asu" or "rehab").
+#' @param parameter Parameter name to filter by ("iat", "los" or "routing").
+#' @param param_function Function to run
+#'
+#' @return Named list of parameters
+
+init_param_class <- function(data, unit, parameter, param_function) {
+
+ # Filter data to specified unit and parameter
+ df_subset <- data[data[["unit"]] == unit &
+ data[["parameter"]] == parameter, ]
+
+ # Create named list of parameter values.
+ # If all SD values are missing, use only means and name by 'type'.
+ # Otherwise, include both mean and sd for each type, with names like
+ # 'type_mean' and 'type_sd'.
+ if (all(is.na(df_subset$sd))) {
+ param_list <- as.list(setNames(df_subset$mean, df_subset$type))
+ } else {
+ param_list <- list()
+ for (i in seq_len(nrow(df_subset))) {
+ df_row <- df_subset[i, ]
+ param_list[[paste0(df_row$type, "_mean")]] <- df_row$mean
+ param_list[[paste0(df_row$type, "_sd")]] <- df_row$sd
+ }
+ }
+
+ # Run parameter function using list
+ do.call(param_function, param_list)
+}
+```
+
+``` r
+#' Generate named_list with create_parameters() using values loaded from a CSV
+#' file.
+#'
+#' @param csv_path Path to csv file containing the parameters. Should have
+#' columns "unit", "parameter", "type", "mean" and "sd". Missing values should
+#' be marked as "NA".
+#'
+#' @return Named list generated by create_parameters()
+
+setup_param_from_csv <- function(csv_path) {
+ # Load parameter data from CSV, treating "NA" as missing values
+ param_data <- read.csv(csv_path, na.strings = "NA")
+
+ # Specify mappings of create_parameters() arguments to their corresponding
+ # units, parameter types and parameter classes
+ param_specs <- list(
+ list(name = "asu_arrivals",
+ unit = "asu",
+ parameter = "iat",
+ param_function = create_asu_arrivals),
+ list(name = "rehab_arrivals",
+ unit = "rehab",
+ parameter = "iat",
+ param_function = create_rehab_arrivals),
+ list(name = "asu_los",
+ unit = "asu",
+ parameter = "los",
+ param_function = create_asu_los),
+ list(name = "rehab_los",
+ unit = "rehab",
+ parameter = "los",
+ param_function = create_rehab_los),
+ list(name = "asu_routing",
+ unit = "asu",
+ parameter = "routing",
+ param_function = create_asu_routing),
+ list(name = "rehab_routing",
+ unit = "rehab",
+ parameter = "routing",
+ param_function = create_rehab_routing)
+ )
+ param_kwargs <- list()
+ for (spec in param_specs) {
+ param_kwargs[[spec$name]] <- init_param_class(
+ data = param_data, unit = spec$unit, parameter = spec$parameter,
+ param_function = spec$param_function
+ )
+ }
+
+ do.call(create_parameters, param_kwargs)
+}
+```
+
+``` r
+setup_param_from_csv(file.path("..", "inputs", "parameters.csv"))
+```
+
+ ## $asu_arrivals
+ ## $asu_arrivals$stroke
+ ## [1] 1.2
+ ##
+ ## $asu_arrivals$tia
+ ## [1] 9.3
+ ##
+ ## $asu_arrivals$neuro
+ ## [1] 3.6
+ ##
+ ## $asu_arrivals$other
+ ## [1] 3.2
+ ##
+ ##
+ ## $rehab_arrivals
+ ## $rehab_arrivals$stroke
+ ## [1] 21.8
+ ##
+ ## $rehab_arrivals$neuro
+ ## [1] 31.7
+ ##
+ ## $rehab_arrivals$other
+ ## [1] 28.6
+ ##
+ ##
+ ## $asu_los
+ ## $asu_los$stroke_no_esd
+ ## $asu_los$stroke_no_esd$mean
+ ## [1] 7.4
+ ##
+ ## $asu_los$stroke_no_esd$sd
+ ## [1] "8.61"
+ ##
+ ##
+ ## $asu_los$stroke_esd
+ ## $asu_los$stroke_esd$mean
+ ## [1] 4.6
+ ##
+ ## $asu_los$stroke_esd$sd
+ ## [1] "4.8"
+ ##
+ ##
+ ## $asu_los$stroke_mortality
+ ## $asu_los$stroke_mortality$mean
+ ## [1] 7
+ ##
+ ## $asu_los$stroke_mortality$sd
+ ## [1] 8.7
+ ##
+ ##
+ ## $asu_los$tia
+ ## $asu_los$tia$mean
+ ## [1] 1.8
+ ##
+ ## $asu_los$tia$sd
+ ## [1] "2.3"
+ ##
+ ##
+ ## $asu_los$neuro
+ ## $asu_los$neuro$mean
+ ## [1] 4
+ ##
+ ## $asu_los$neuro$sd
+ ## [1] "5"
+ ##
+ ##
+ ## $asu_los$other
+ ## $asu_los$other$mean
+ ## [1] 3.8
+ ##
+ ## $asu_los$other$sd
+ ## [1] "5.2"
+ ##
+ ##
+ ##
+ ## $rehab_los
+ ## $rehab_los$stroke_no_esd
+ ## $rehab_los$stroke_no_esd$mean
+ ## [1] 28.4
+ ##
+ ## $rehab_los$stroke_no_esd$sd
+ ## [1] "27.2"
+ ##
+ ##
+ ## $rehab_los$stroke_esd
+ ## $rehab_los$stroke_esd$mean
+ ## [1] 30.3
+ ##
+ ## $rehab_los$stroke_esd$sd
+ ## [1] "2un3.1"
+ ##
+ ##
+ ## $rehab_los$tia
+ ## $rehab_los$tia$mean
+ ## [1] 18.7
+ ##
+ ## $rehab_los$tia$sd
+ ## [1] "23.5"
+ ##
+ ##
+ ## $rehab_los$neuro
+ ## $rehab_los$neuro$mean
+ ## [1] 27.6
+ ##
+ ## $rehab_los$neuro$sd
+ ## [1] "28.4"
+ ##
+ ##
+ ## $rehab_los$other
+ ## $rehab_los$other$mean
+ ## [1] 16.1
+ ##
+ ## $rehab_los$other$sd
+ ## [1] "14.1"
+ ##
+ ##
+ ##
+ ## $asu_routing
+ ## $asu_routing$stroke
+ ## $asu_routing$stroke$rehab
+ ## [1] 0.24
+ ##
+ ## $asu_routing$stroke$esd
+ ## [1] 0.13
+ ##
+ ## $asu_routing$stroke$other
+ ## [1] 0.63
+ ##
+ ##
+ ## $asu_routing$tia
+ ## $asu_routing$tia$rehab
+ ## [1] 0.01
+ ##
+ ## $asu_routing$tia$esd
+ ## [1] 0.01
+ ##
+ ## $asu_routing$tia$other
+ ## [1] 0.98
+ ##
+ ##
+ ## $asu_routing$neuro
+ ## $asu_routing$neuro$rehab
+ ## [1] 0.11
+ ##
+ ## $asu_routing$neuro$esd
+ ## [1] 0.05
+ ##
+ ## $asu_routing$neuro$other
+ ## [1] 0.84
+ ##
+ ##
+ ## $asu_routing$other
+ ## $asu_routing$other$rehab
+ ## [1] 0.05
+ ##
+ ## $asu_routing$other$esd
+ ## [1] 0.1
+ ##
+ ## $asu_routing$other$other
+ ## [1] 0.85
+ ##
+ ##
+ ##
+ ## $rehab_routing
+ ## $rehab_routing$stroke
+ ## $rehab_routing$stroke$esd
+ ## [1] 0.4
+ ##
+ ## $rehab_routing$stroke$other
+ ## [1] 0.6
+ ##
+ ##
+ ## $rehab_routing$tia
+ ## $rehab_routing$tia$esd
+ ## [1] 0
+ ##
+ ## $rehab_routing$tia$other
+ ## [1] 1
+ ##
+ ##
+ ## $rehab_routing$neuro
+ ## $rehab_routing$neuro$esd
+ ## [1] 0.09
+ ##
+ ## $rehab_routing$neuro$other
+ ## [1] 0.91
+ ##
+ ##
+ ## $rehab_routing$other
+ ## $rehab_routing$other$esd
+ ## [1] 0.13
+ ##
+ ## $rehab_routing$other$other
+ ## [1] 0.88
+ ##
+ ##
+ ##
+ ## $warm_up_period
+ ## [1] 1095
+ ##
+ ## $data_collection_period
+ ## [1] 1825
+ ##
+ ## $number_of_runs
+ ## [1] 150
+ ##
+ ## $scenario_name
+ ## NULL
+ ##
+ ## $cores
+ ## [1] 1
+ ##
+ ## $log_to_console
+ ## [1] FALSE
+ ##
+ ## $log_to_file
+ ## [1] FALSE
+ ##
+ ## $file_path
+ ## NULL
+
+## Calculate run time
+
+``` r
+# Get run time in seconds
+end_time <- Sys.time()
+runtime <- as.numeric(end_time - start_time, units = "secs")
+
+# Display converted to minutes and seconds
+minutes <- as.integer(runtime / 60L)
+seconds <- as.integer(runtime %% 60L)
+cat(sprintf("Notebook run time: %dm %ds", minutes, seconds))
+```
+
+ ## Notebook run time: 0m 0s
diff --git a/tests/testthat/test-functionaltest.R b/tests/testthat/test-functionaltest.R
index 6485221..3d2b70a 100644
--- a/tests/testthat/test-functionaltest.R
+++ b/tests/testthat/test-functionaltest.R
@@ -28,8 +28,8 @@ test_that("model errors for invalid asu_arrivals values", {
test_that("model errors for invalid asu_los values", {
param <- create_parameters()
- # Negative mean for stroke_noesd
- param$asu_los$stroke_noesd$mean <- -5L
+ # Negative mean for stroke_no_esd
+ param$asu_los$stroke_no_esd$mean <- -5L
expect_error(
model(param = param, run_number = 1L),
'All values in "asu_los" must be greater than 0.'
@@ -169,7 +169,7 @@ patrick::with_parameters_test_that(
patrick::cases(
list(group = "asu_arrivals", patient = "stroke", metric = NULL,
init_value = 2L, adj_value = 6L),
- list(group = "rehab_los", patient = "stroke_noesd", metric = "mean",
+ list(group = "rehab_los", patient = "stroke_no_esd", metric = "mean",
init_value = 30L, adj_value = 10L)
)
)