fitting square data into round models
09 October 2023
Stock-flow model
Dynamic behaviour, feedback loops
‘admissions per day’ is needed to populate the model.
‘discharged’ could be used to verify the model against known data
‘on ward’ is used to verify the model against known data
Easy to do with count
, or group_by
and summarise
Generate list of key dates
Iterate over each date - need to have been admitted before, and discharged after
occupancy_flag <- function(df) {
# pre-allocate tibble size to speed up iteration in loop
activity_all <- tibble(nrow = nrow(df)) |>
select()
for (i in 1:run_len) {
activity_period <- case_when(
# creates 1 flag if resident for complete day
df$date_admit < keydates$keydate[i] &
df$date_discharge > keydates$keydate[i] ~ 1,
TRUE ~ 0)
# column bind this day's flags to previous
activity_all <- bind_cols(activity_all, activity_period)
}
# rename column to match the day being counted
activity_all <- activity_all |>
setNames(paste0("d_", keydates$date))
# bind flags columns to patient data
daily_adm <- bind_cols(df, activity_all) |>
pivot_longer(
cols = starts_with("d_"),
names_to = "date",
values_to = "count"
) |>
group_by(date) |>
summarise(resident = sum(count)) |>
ungroup() |>
mutate(date = str_remove(date, "d_"))
}
Is there a better way than using a for
loop?
Use lubridate::floor_date
to generate the date at start of week/month
# A tibble: 6 × 2
week_start n
<date> <int>
1 2021-12-27 52
2 2022-01-03 196
3 2022-01-10 192
4 2022-01-17 223
5 2022-01-24 157
6 2022-01-31 187
Key dates to include the dates at the start and end of each time period
wk_start wk_end
1 2022-01-03 2022-01-09
2 2022-01-10 2022-01-16
3 2022-01-17 2022-01-23
4 2022-01-24 2022-01-30
5 2022-01-31 2022-02-06
6 2022-02-07 2022-02-13
More logic required if working in weeks or months - can only be in one place at any given time
Generalise function to a state where it can be used by others - onto Github
Turn this into a package
Open-source SD models and interfaces - R Shiny or Python
NHS-R conference 2023