Skip to content

Commit 45f6b59

Browse files
authored
Merge pull request #89 from pythonhealthdatascience/dev
Dev
2 parents 437fac4 + 84188d4 commit 45f6b59

File tree

67 files changed

+2657
-1141
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+2657
-1141
lines changed

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
^.*\.Rproj$
44
^\.Rproj\.user$
55
^LICENSE\.md$
6+
^CODE_OF_CONDUCT\.md$
67
^CONTRIBUTING\.md$
78
^docs$
89
^images$

CODE_OF_CONDUCT.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Contributor Covenant Code of Conduct
2+
3+
## Our Pledge
4+
5+
We as members, contributors, and leaders pledge to make participation in our
6+
community a harassment-free experience for everyone, regardless of age, body
7+
size, visible or invisible disability, ethnicity, sex characteristics, gender
8+
identity and expression, level of experience, education, socio-economic status,
9+
nationality, personal appearance, race, caste, color, religion, or sexual
10+
identity and orientation.
11+
12+
We pledge to act and interact in ways that contribute to an open, welcoming,
13+
diverse, inclusive, and healthy community.
14+
15+
## Our Standards
16+
17+
Examples of behavior that contributes to a positive environment for our
18+
community include:
19+
20+
- Demonstrating empathy and kindness toward other people
21+
- Being respectful of differing opinions, viewpoints, and experiences
22+
- Giving and gracefully accepting constructive feedback
23+
- Accepting responsibility and apologizing to those affected by our mistakes,
24+
and learning from the experience
25+
- Focusing on what is best not just for us as individuals, but for the overall
26+
community
27+
28+
Examples of unacceptable behavior include:
29+
30+
- The use of sexualized language or imagery, and sexual attention or advances of
31+
any kind
32+
- Trolling, insulting or derogatory comments, and personal or political attacks
33+
- Public or private harassment
34+
- Publishing others' private information, such as a physical or email address,
35+
without their explicit permission
36+
- Other conduct which could reasonably be considered inappropriate in a
37+
professional setting
38+
39+
## Enforcement Responsibilities
40+
41+
Community leaders are responsible for clarifying and enforcing our standards of
42+
acceptable behavior and will take appropriate and fair corrective action in
43+
response to any behavior that they deem inappropriate, threatening, offensive,
44+
or harmful.
45+
46+
Community leaders have the right and responsibility to remove, edit, or reject
47+
comments, commits, code, wiki edits, issues, and other contributions that are
48+
not aligned to this Code of Conduct, and will communicate reasons for moderation
49+
decisions when appropriate.
50+
51+
## Scope
52+
53+
This Code of Conduct applies within all community spaces, and also applies when
54+
an individual is officially representing the community in public spaces.
55+
Examples of representing our community include using an official email address,
56+
posting via an official social media account, or acting as an appointed
57+
representative at an online or offline event.
58+
59+
## Enforcement
60+
61+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
62+
reported to the community leaders responsible for enforcement at
63+
[INSERT CONTACT METHOD].
64+
All complaints will be reviewed and investigated promptly and fairly.
65+
66+
All community leaders are obligated to respect the privacy and security of the
67+
reporter of any incident.
68+
69+
## Enforcement Guidelines
70+
71+
Community leaders will follow these Community Impact Guidelines in determining
72+
the consequences for any action they deem in violation of this Code of Conduct:
73+
74+
### 1. Correction
75+
76+
**Community Impact**: Use of inappropriate language or other behavior deemed
77+
unprofessional or unwelcome in the community.
78+
79+
**Consequence**: A private, written warning from community leaders, providing
80+
clarity around the nature of the violation and an explanation of why the
81+
behavior was inappropriate. A public apology may be requested.
82+
83+
### 2. Warning
84+
85+
**Community Impact**: A violation through a single incident or series of
86+
actions.
87+
88+
**Consequence**: A warning with consequences for continued behavior. No
89+
interaction with the people involved, including unsolicited interaction with
90+
those enforcing the Code of Conduct, for a specified period of time. This
91+
includes avoiding interactions in community spaces as well as external channels
92+
like social media. Violating these terms may lead to a temporary or permanent
93+
ban.
94+
95+
### 3. Temporary Ban
96+
97+
**Community Impact**: A serious violation of community standards, including
98+
sustained inappropriate behavior.
99+
100+
**Consequence**: A temporary ban from any sort of interaction or public
101+
communication with the community for a specified period of time. No public or
102+
private interaction with the people involved, including unsolicited interaction
103+
with those enforcing the Code of Conduct, is allowed during this period.
104+
Violating these terms may lead to a permanent ban.
105+
106+
### 4. Permanent Ban
107+
108+
**Community Impact**: Demonstrating a pattern of violation of community
109+
standards, including sustained inappropriate behavior, harassment of an
110+
individual, or aggression toward or disparagement of classes of individuals.
111+
112+
**Consequence**: A permanent ban from any sort of public interaction within the
113+
community.
114+
115+
## Attribution
116+
117+
This Code of Conduct is adapted from the
118+
[Contributor Covenant](https://www.contributor-covenant.org/), version 2.1,
119+
available at
120+
<https://www.contributor-covenant.org/version/2/1/code_of_conduct/>.
121+
122+
Community Impact Guidelines were inspired by
123+
[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/inclusion).
124+
125+
For answers to common questions about this code of conduct, see the FAQ at
126+
<https://www.contributor-covenant.org/faq/>. Translations are available at
127+
<https://www.contributor-covenant.org/translations/>.

CONTRIBUTING.md

Lines changed: 116 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,124 @@
11
# Contributing
22

3-
🎉 Thank you for checking out our project! 🎉
3+
Thank you for your interest in contributing! 🤗
44

5-
This file contains guidelines on how to get in touch with us and potentially contribute towards this repository.
5+
This file covers:
66

7-
## Email
7+
* 🐞 Workflow for bug reports, feature requests and documentation improvements
8+
* 🚀 Workflow for code contributions (bug fixes, enhancements)
9+
* 🛠️ Development and testing
10+
* 📦 Updating the package
11+
* 🤝 Code of conduct
812

9-
You can contact the researchers on this project using the provided email addresses in `CITATION.cff`.
13+
<br>
1014

11-
## Suggesting changes
15+
## 🐞 Workflow for bug reports, feature requests and documentation improvements
1216

13-
If you spot an issue, you are welcome to raise this either by:
17+
Before opening an issue, please search [existing issues](https://github.com/pythonhealthdatascience/rdesrap_mms/issues) to avoid duplicates. If an issue exists, you can add a comment with additional details and/or upvote (👍) the issue. If there is not an existing issue, please open one and provide as much detail as possible.
1418

15-
* Using **GitHub Issues**.
16-
* **Forking** the repository, make your changes and submit a pull request for review.
19+
* **For feature requests or documentation improvements**, please describe your suggestion clearly.
20+
* **For bugs**, include:
21+
* Steps to reproduce.
22+
* Expected and actual behaviour.
23+
* Environment details (operating system, R version, dependencies).
24+
* Relevant files (e.g. problematic `.qmd` files).
25+
26+
### Handling bug reports (for maintainers):
27+
28+
* Confirm reproducibility by following the reported steps.
29+
* Label the issue appropriately (e.g. `bug`).
30+
* Request additional information if necessary.
31+
* Link related issues or pull requests.
32+
* Once resolved, close the issue with a brief summary of the fix.
33+
34+
<br>
35+
36+
## 🚀 Workflow for code contributions (bug fixes, enhancements)
37+
38+
1. Fork the repository and clone your fork.
39+
40+
2. Create a new branch for your feature or fix:
41+
42+
```{.bash}
43+
git checkout -b my-feature
44+
```
45+
46+
3. Make your changes and commit them with clear, descriptive messages using the [conventional commits standard](https://www.conventionalcommits.org/en/v1.0.0/).
47+
48+
4. Push your branch to your fork:
49+
50+
```{.bash}
51+
git push origin my-feature
52+
```
53+
54+
5. Open a pull request against the main branch. Describe your changes and reference any related issues.
55+
56+
<br>
57+
58+
## 🛠️ Development and testing
59+
60+
### Dependencies
61+
62+
Set up the R environment using `renv` (recommended):
63+
64+
```{.r}
65+
renv::init()
66+
renv::restore()
67+
```
68+
69+
If you encounter issues restoring the exact environment, you can install dependencies from `DESCRIPTION` and generate your own lock file:
70+
71+
```{.r}
72+
renv::init()
73+
renv::install()
74+
renv::snapshot()
75+
```
76+
77+
Some packages (e.g. `igraph`) may require system libraries. For example, for Ubuntu:
78+
79+
```{.bash}
80+
sudo apt install build-essential gfortran
81+
sudo apt install libglpk-dev libxml2-dev
82+
```
83+
84+
<br>
85+
86+
### Tests
87+
88+
Run tests:
89+
90+
```{.r}
91+
devtools::test()
92+
```
93+
94+
Compute test coverage:
95+
96+
```{.r}
97+
devtools::test_coverage()
98+
```
99+
100+
<br>
101+
102+
### Linting
103+
104+
```{.r}
105+
lintr::lint_dir()
106+
```
107+
108+
<br>
109+
110+
## 📦 Updating the package
111+
112+
If you are a maintainer and need to publish a new release:
113+
114+
1. Update `NEWS.md`.
115+
116+
2. Update the version number in `DESCRIPTION`, `CITATION.cff` and `CITATION`, and update the date in `CITATION.cff`.
117+
118+
3. Create a release on GitHub, which will automatically archive to Zenodo.
119+
120+
<br>
121+
122+
## 🤝 Code of conduct
123+
124+
Please be respectful and considerate. See the [code of conduct](https://github.com/pythonhealthdatascience/rdesrap_mms/blob/main/CODE_OF_CONDUCT.md) for details.

DESCRIPTION

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: simulation
22
Type: Package
33
Title: Simulation
4-
Version: 0.1.0
4+
Version: 0.4.0
55
Authors@R: c(
66
person(
77
"Amy", "Heather",
@@ -18,7 +18,6 @@ LazyData: true
1818
RoxygenNote: 7.3.2
1919
Imports:
2020
simmer,
21-
magrittr,
2221
dplyr,
2322
purrr,
2423
rlang,
@@ -42,5 +41,6 @@ Suggests:
4241
lubridate,
4342
plotly,
4443
covr,
45-
DT
44+
DT,
45+
queueing
4646
Config/testthat/edition: 3

NAMESPACE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export(calc_mean_wait)
1111
export(calc_unseen_mean)
1212
export(calc_unseen_n)
1313
export(calc_utilisation)
14+
export(check_log_file_path)
1415
export(confidence_interval_method)
1516
export(filter_warmup)
1617
export(get_run_results)
@@ -53,7 +54,6 @@ importFrom(ggplot2,ggsave)
5354
importFrom(ggplot2,labs)
5455
importFrom(ggplot2,theme_minimal)
5556
importFrom(gridExtra,marrangeGrob)
56-
importFrom(magrittr,"%>%")
5757
importFrom(purrr,reduce)
5858
importFrom(rlang,.data)
5959
importFrom(simmer,add_generator)

R/choose_replications.R

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ WelfordStats <- R6Class("WelfordStats", list( # nolint: object_name_linter
114114
#' @description Computes the precision of the confidence interval expressed
115115
#' as the percentage deviation of the half width from the mean.
116116
deviation = function() {
117-
self$half_width() / self$mean
117+
mw <- self$mean
118+
if (is.na(mw) || mw == 0L) return(NA_real_)
119+
self$half_width() / mw
118120
}
119121
))
120122

@@ -413,7 +415,13 @@ ReplicationsAlgorithm <- R6Class("ReplicationsAlgorithm", list( # nolint: object
413415

414416
# Whilst have not yet got all metrics marked as solved = TRUE, and still
415417
# under replication budget + lookahead...
416-
while (!all(unlist(lapply(solutions, function(x) x$solved))) &&
418+
is_all_solved <- function(solutions_list) {
419+
statuses <- unlist(lapply(solutions_list, function(x) x$solved))
420+
# If any are NA or FALSE, treat as not solved
421+
all(statuses)
422+
}
423+
424+
while (!is_all_solved(solutions) &&
417425
self$reps < self$replication_budget + self$klimit()) {
418426

419427
# Increment counter
@@ -455,6 +463,7 @@ ReplicationsAlgorithm <- R6Class("ReplicationsAlgorithm", list( # nolint: object
455463
# If precision was not achieved, ensure nreps is None (e.g. in cases
456464
# where precision is lost after a success)
457465
solutions[[metric]]$nreps <- NA
466+
solutions[[metric]]$target_met <- 0L
458467
}
459468

460469
}

R/get_run_results.R

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ get_run_results <- function(results, run_number) {
3737
calc_mean_serve_length(results[["arrivals"]], results[["resources"]]),
3838
calc_utilisation(results[["resources"]]),
3939
calc_unseen_n(results[["arrivals"]]),
40-
calc_unseen_mean(results[["arrivals"]])
40+
calc_unseen_mean(results[["arrivals"]]),
41+
calc_mean_time_in_system(results[["arrivals"]])
4142
)
4243
# Combine metrics + replication number in a single dataframe
4344
dplyr::bind_cols(tibble(replication = run_number), metrics)
@@ -319,3 +320,24 @@ calc_unseen_mean <- function(arrivals, groups = NULL) {
319320
names_glue = "mean_waiting_time_unseen_{resource}") |>
320321
ungroup()
321322
}
323+
324+
325+
#' Calculate the mean time in the system for finished patients.
326+
#'
327+
#' @param arrivals Dataframe with times for each patient with each resource.
328+
#' @param groups Optional list of columns to group by for the calculation.
329+
#'
330+
#' @return Tibble with column containing the mean time in the system.
331+
332+
calc_mean_time_in_system <- function(arrivals, groups = NULL) {
333+
# If provided, group the dataset
334+
if (!is.null(groups)) {
335+
arrivals <- group_by(arrivals, across(all_of(groups)))
336+
}
337+
# Calculate number of arrivals
338+
arrivals |>
339+
summarise(
340+
mean_time_in_system = mean(.data[["time_in_system"]], na.rm = TRUE)
341+
) |>
342+
ungroup()
343+
}

0 commit comments

Comments
 (0)