|
| 1 | +#' Create acute stroke unit (ASU) patient trajectory. |
| 2 | +#' |
| 3 | +#' Represents patient stay in the ASU - samples their (1) destination after |
| 4 | +#' the ASU, and (2) length of stay (LOS) on the ASU. |
| 5 | +#' |
| 6 | +#' @param env Simmer environment object. The simulation environment where |
| 7 | +#' generators will be added. |
| 8 | +#' @param patient_type Character string specifying patient category. Must be |
| 9 | +#' one of: "stroke", "tia", "neuro", or "other". Determines which arrival rate |
| 10 | +#' parameter is used. |
| 11 | +#' @param param Nested list containing simulation parameters. Must have |
| 12 | +#' structure \code{param$asu_routing$<patient_type>} containing the probability |
| 13 | +#' of routing to each destination (e.g. |
| 14 | +#' \code{param$asu_routing$stroke$rehab = 0.24}). |
| 15 | +#' |
| 16 | +#' @importFrom simmer branch get_attribute log_ set_attribute timeout trajectory |
| 17 | +#' @importFrom stats rlnorm |
| 18 | +#' |
| 19 | +#' @return Simmer trajectory object. Defines patient journey logic through the |
| 20 | +#' healthcare system. |
| 21 | +#' @export |
| 22 | + |
| 23 | +create_asu_trajectory <- function(env, patient_type, param) { |
| 24 | + |
| 25 | + # Set up simmer trajectory object... |
| 26 | + trajectory(paste0("ASU_", patient_type, "_path")) |> |
| 27 | + |
| 28 | + log_("🚶 Arrived at ASU") |> |
| 29 | + |
| 30 | + # Sample destination after ASU (as destination influences length of stay) |
| 31 | + set_attribute("post_asu_destination", function() { |
| 32 | + sample_routing(prob_list = param[["asu_routing"]][[patient_type]]) |
| 33 | + }) |> |
| 34 | + |
| 35 | + log_(function() { |
| 36 | + # Retrieve attribute, and use to get post-ASU destination as a string |
| 37 | + dest_index <- get_attribute(env, "post_asu_destination") |
| 38 | + dest_names <- names(param[["asu_routing"]][[patient_type]]) |
| 39 | + dest <- dest_names[dest_index] |
| 40 | + # Create log message |
| 41 | + paste0("🎯 Planned ASU -> ", dest_index, " (", dest, ")") |
| 42 | + }) |> |
| 43 | + |
| 44 | + set_attribute("asu_los", function() { |
| 45 | + # Retrieve attribute, and use to get post-ASU destination as a string |
| 46 | + dest_index <- get_attribute(env, "post_asu_destination") |
| 47 | + dest_names <- names(param[["asu_routing"]][[patient_type]]) |
| 48 | + dest <- dest_names[dest_index] |
| 49 | + |
| 50 | + # Determine which LOS distribution to use |
| 51 | + if (patient_type == "stroke") { |
| 52 | + los_params <- switch( |
| 53 | + dest, |
| 54 | + esd = param[["asu_los_lnorm"]][["stroke_esd"]], |
| 55 | + rehab = param[["asu_los_lnorm"]][["stroke_noesd"]], |
| 56 | + other = param[["asu_los_lnorm"]][["stroke_mortality"]], |
| 57 | + stop("Stroke post-asu destination '", dest, "' invalid", |
| 58 | + call. = FALSE) |
| 59 | + ) |
| 60 | + } else { |
| 61 | + los_params <- param[["asu_los_lnorm"]][[patient_type]] |
| 62 | + } |
| 63 | + |
| 64 | + # Sample LOS from lognormal |
| 65 | + rlnorm( |
| 66 | + n = 1L, |
| 67 | + meanlog = los_params[["meanlog"]], |
| 68 | + sdlog = los_params[["sdlog"]] |
| 69 | + ) |
| 70 | + }) |> |
| 71 | + |
| 72 | + log_(function() { |
| 73 | + paste0("⏳ ASU length of stay: ", |
| 74 | + round(get_attribute(env, "asu_los"), 3L)) |
| 75 | + }) |> |
| 76 | + |
| 77 | + timeout(function() get_attribute(env, "asu_los")) |> |
| 78 | + |
| 79 | + log_("🏁 ASU stay completed") |> |
| 80 | + |
| 81 | + # If that patient's destination is rehab, then start on that trajectory |
| 82 | + branch( |
| 83 | + option = function() { |
| 84 | + # Retrieve attribute, and use to get post-ASU destination as a string |
| 85 | + dest_index <- get_attribute(env, "post_asu_destination") |
| 86 | + dest_names <- names(param[["asu_routing"]][[patient_type]]) |
| 87 | + dest <- dest_names[dest_index] |
| 88 | + # Return 1 for rehab and 0 otherwise |
| 89 | + if (dest == "rehab") 1L else 0L |
| 90 | + }, |
| 91 | + continue = FALSE, # Do not continue main trajectory after branch |
| 92 | + create_rehab_trajectory(env, patient_type, param) |
| 93 | + ) |
| 94 | +} |
0 commit comments