1- # ' Get results from each replication .
1+ # ' Process the raw monitored arrivals and resources .
22# '
3- # ' For each replication (there can be one or many), calculate the: (1) number
4- # ' of arrivals, (2) mean wait time for each resource, (3) mean activity time
5- # ' for each resource, and (4) mean resource utilisation.
3+ # ' For the provided replication, calculate the:
4+ # ' (1) number of arrivals
5+ # ' (2) mean wait time for each resource
6+ # ' (3) mean activity time for each resource
7+ # ' (4) mean resource utilisation.
68# '
79# ' Credit: The utilisation calculation is taken from the
810# ' `plot.resources.utilization()` function in simmer.plot 0.1.18, which is
1820# ' @param results Named list with `arrivals` containing output from
1921# ' `get_mon_arrivals()` and `resources` containing output from
2022# ' `get_mon_resources()` (`per_resource = TRUE` and `ongoing = TRUE`).
21- # ' @param param Named list of model parameters .
23+ # ' @param run_number Integer representing index of current simulation run .
2224# '
2325# ' @importFrom dplyr group_by summarise n_distinct mutate lead full_join
26+ # ' @importFrom dplyr bind_cols
2427# ' @importFrom purrr reduce
2528# ' @importFrom rlang .data
2629# ' @importFrom simmer get_mon_resources get_mon_arrivals now
2730# ' @importFrom tidyr pivot_wider drop_na
2831# ' @importFrom tidyselect any_of
32+ # ' @importFrom tibble tibble
2933# '
30- # ' @return Tibble with results from each replication.
34+ # ' @return Tibble with processed results from replication.
3135# ' @export
3236
33- get_run_results <- function (results , param ) {
37+ get_run_results <- function (results , run_number ) {
3438
35- # Create a tibble with all replication numbers
36- all_replications <- tibble :: tibble(replication = 1 : param [[" number_of_runs" ]])
39+ # Remove patients who were still waiting and had not completed
40+ results [[" arrivals" ]] <- results [[" arrivals" ]] %> %
41+ drop_na(any_of(" end_time" ))
3742
38- # If there are any arrivals in any replication...
39- if (nrow(results [[" arrivals" ]]) > 0 ) {
40-
41- # Remove patients who were still waiting and had not completed
42- results [[" arrivals" ]] <- results [[" arrivals" ]] %> %
43- drop_na(any_of(" end_time" ))
43+ # If there are any arrivals...
44+ if (nrow(results [[" arrivals" ]]) > 0L ) {
4445
4546 # Calculate the number of arrivals
4647 calc_arr <- results [[" arrivals" ]] %> %
47- group_by(.data [[" replication" ]]) %> %
4848 summarise(arrivals = n_distinct(.data [[" name" ]]))
4949
5050 # Calculate the mean wait time for each resource
@@ -56,15 +56,15 @@ get_run_results <- function(results, param) {
5656 ), 10L
5757 )
5858 ) %> %
59- group_by(.data [[" resource" ]], .data [[ " replication " ]] ) %> %
59+ group_by(.data [[" resource" ]]) %> %
6060 summarise(mean_waiting_time = mean(.data [[" waiting_time" ]])) %> %
6161 pivot_wider(names_from = " resource" ,
6262 values_from = " mean_waiting_time" ,
6363 names_glue = " mean_waiting_time_{resource}" )
6464
6565 # Calculate the mean time spent with each resource
6666 calc_act <- results [[" arrivals" ]] %> %
67- group_by(.data [[" resource" ]], .data [[ " replication " ]] ) %> %
67+ group_by(.data [[" resource" ]]) %> %
6868 summarise(mean_activity_time = mean(.data [[" activity_time" ]])) %> %
6969 pivot_wider(names_from = " resource" ,
7070 values_from = " mean_activity_time" ,
@@ -74,12 +74,13 @@ get_run_results <- function(results, param) {
7474 # Utilisation is given by the total effective usage time (`in_use`) over the
7575 # total time intervals considered (`dt`).
7676 calc_util <- results [[" resources" ]] %> %
77- group_by(.data [[" resource" ]], .data [[ " replication " ]] ) %> %
77+ group_by(.data [[" resource" ]]) %> %
7878 # nolint start
7979 mutate(dt = lead(.data [[" time" ]]) - .data [[" time" ]]) %> %
8080 mutate(capacity = pmax(.data [[" capacity" ]], .data [[" server" ]])) %> %
8181 mutate(dt = ifelse(.data [[" capacity" ]] > 0L , .data [[" dt" ]], 0L )) %> %
82- mutate(in_use = .data [[" dt" ]] * .data [[" server" ]] / .data [[" capacity" ]]) %> %
82+ mutate(in_use = (.data [[" dt" ]] * .data [[" server" ]] /
83+ .data [[" capacity" ]])) %> %
8384 # nolint end
8485 summarise(
8586 utilisation = sum(.data [[" in_use" ]], na.rm = TRUE ) /
@@ -89,20 +90,18 @@ get_run_results <- function(results, param) {
8990 values_from = " utilisation" ,
9091 names_glue = " utilisation_{resource}" )
9192
92- # Combine all calculated metrics into a single dataframe
93- processed_result <- list (calc_arr , calc_wait , calc_act , calc_util ) %> %
94- reduce(full_join , by = " replication" )
95-
96- # Join with all_replications to ensure all runs are represented
97- processed_result <- dplyr :: full_join(
98- all_replications , processed_result , by = " replication" ) %> %
99- # Replace NA in 'arrivals' column with 0
100- mutate(arrivals = ifelse(is.na(arrivals ), 0 , arrivals ))
101-
102- # If there were no patients in any replication, return NULL
93+ # Combine all calculated metrics into a single dataframe, and along with
94+ # the replication number
95+ processed_result <- dplyr :: bind_cols(
96+ tibble(replication = run_number ),
97+ calc_arr , calc_wait , calc_act , calc_util
98+ )
10399 } else {
104- processed_result <- NULL
100+ # If there were no arrivals, return dataframe row with just the replication
101+ # number and arrivals column set to 0
102+ processed_result <- tibble(replication = run_number ,
103+ arrivals = nrow(results [[" arrivals" ]]))
105104 }
106105
107- return (processed_result )
106+ return (processed_result ) # nolint
108107}
0 commit comments