knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
require("vctrs") require("slider") require("dplyr") require("parallel") require("simmer") require("simmer.plot") require("ggplot2") require("lubridate") require("tidyverse") require("plotly") require("babsim.hospital")
## install.packages("devtools") ## devtools::install_github("r-lib/devtools") url <- "http://owos.gm.fh-koeln.de:8055/bartz/spot.git" devtools::install_git(url = url) library(SPOT) packageVersion("SPOT")
dataCovidBeds20200624
is a data frame of COVID-19 cases with 114 obs. ofThe function getObkData
generates a list that contains two data frames:
1. simData and
2. field data.
data <- getObkData() simData <- data$simData fieldData <- data$fieldData conf <- babsimToolsConf()
Perform the simulation
conf <- getConfFromData(conf = conf, simData = simData, fieldData = fieldData) set.seed(conf$seed) para <- babsimHospitalPara() arrivalTimes <- getArrivalTimes(simData$Infected) envs <- babsimHospital(arrivalTimes = arrivalTimes, conf = conf, para = para )
Plot resource usage
resources <- get_mon_resources(envs) resources$capacity <- resources$capacity/1e5 plot(resources, metric = "usage", conf$ResourceNames, items = "server")
Get real data (field data)
fieldEvents <- getRealBeds(data = fieldData, resource=c('bed', 'intensiveBed', 'intensiveBedVentilation')) res <- getDailyMaxResults(conf=conf, envs = envs, fieldEvents = fieldEvents) ## save as default: (errDefault <- getError(conf=conf, res))
plotDailyMaxResults(res)
expName <- "obkNoise35" require("SPOT") require("babsim.hospital") require("simmer") ########################################################## data <- getObkData() ########################################################### ## n = number of function evaluations, Anzahl der 30-dim x Vektoren, die getestet werden n = 35 ## k = Groesse des initialen Designs für SPOT (k < n) k = 30 ## m = Anzahl der Simulationswiederholungen für Simnf m = 2 ## parallele Auswertung? PARALLEL = FALSE ## ICU = FALSE ## PERCORES = 0.5 ## Anzahl der Punkte, die von SPOT fuer das Metamodell verwendet werden. Sollte ## fuer Kriging nicht zu gross gewählt werden (<100): SUBSET = 50 ############################################################# x0 <- getStartParameter() bounds <- getBounds() conf = babsimToolsConf() set.seed(conf$seed) conf$parallel = PARALLEL conf$simRepeats = m conf$ICU = ICU conf$percCores = PERCORES conf$logLevel =1 FILENAME <- paste0("../Results.d/run", expName, ".RData") assign( expName, spot( x = x0, fun = funWrapOptimizeSim, lower = bounds$lower, upper = bounds$upper, control = list( funEvals = n, noise = TRUE, optimizer = optimLBFGSB, model = buildKriging, plots = FALSE, progress = TRUE, subsetSelect = selectN, subsetControl = list(N = SUBSET), designControl = list(size = k) ), conf = conf, data = data ) ) # save(list = eval(parse(text = "expName")) , file = FILENAME)
babsim
package, which can be loaded as follows:amntDaysSickness <- 20 obk <- dataCovidBeds20200624 obk$Sick2 <- slide_dbl(obk$Infected, ~sum(.x), .before = (amntDaysSickness -1)) str(obk) sum(obk$Sick- obk$Sick2)
obk$InfCum <- cumsum(obk$Infected)
{plot(obk$Day, obk$InfCum, type="l", log="y", ylim=c(1,500)) lines(obk$Day, obk$Infected + 1e-6)}
obk$InfectedSlideWeek <- slide_dbl(obk$Infected, ~mean(.x), .before = (7 -1)) obk$InfectedSlide2Weeks <- slide_dbl(obk$Infected, ~mean(.x), .before = (14 -1))
{plot(obk$Day, obk$Infected, type="l") lines(obk$Day, obk$InfectedSlideWeek, col = "green") lines(obk$Day, obk$InfectedSlide2Weeks, col = "grey") legend('topright', lty = 1, c("infected", "infectedWeek", "infected2Weeks"), col = c("black", "green", "grey")) }
{plot(obk$Day, obk$Infected, type="l") lines(obk$Day, obk$InfectedSlideWeek, col = "green") lines(obk$Day, obk$bed, col = "blue") lines(obk$Day, obk$intensiveBed, col = "orange") lines(obk$Day, obk$intensiveBedVentilation, col = "red") legend('topright', lty = 1, c("infected", "infectedWeek", "normal", "intens", "vent"), col = c("black", "green", "blue", "orange", "red")) }
To define the simulation period, the obk
data will be used:
\begin{itemize}
\item StartDate
: the day, logging of real data starts, e.g., "2020-03-03"
\item EndDate
: last day for simulations, e.g. "2020-05-07"
\end{itemize}
The observedPeriod is defined as the complete period, which will be analyzed in this project, e.g.,
observedPeriod = 1 + EndData - StartDate.
StartDate <- obk$Day[1] EndDate <- obk$Day[length(obk$Day)] observedPeriod = 1 + as.numeric(as.Date(EndDate)- as.Date(StartDate))
infectedPerDay <- obk$Infected infectedPerDayCum <- cumsum(infectedPerDay) obk$Sick <- slide_dbl(obk$Infected, ~sum(.x), .before = (amntDaysSickness -1)) # print(data.frame(day = 1:length(infectedPerDay), infected= infectedPerDay, sick = obk$Sick, infectedCum = infectedPerDayCum))
{plot(obk$Day, obk$InfCum, type="l") lines(obk$Day, obk$Infected, col = "red") lines(obk$Day, obk$Sick, col = "blue") }
obk
data again.arrivalTimes
for the simulation.str(obk) set.seed(123) arrivalTimes <- getArrivalTimes(obk$Infected) str(arrivalTimes)
babsimHospital
function.conf = babsimToolsConf() conf$simRepeats = 10 conf$logLevel = 0 conf$seed = 123 y <- babsimHospital(arrivalTimes = arrivalTimes , conf = conf , para = babsimHospitalPara() )
obk
data set. GAData <- data.frame(bed=obk$bed, intensiveBed=obk$intensiveBed, intensiveBedVentilation=obk$intensiveBedVentilation, Day = obk$Day) GABeds <- getRealBeds(data = GAData, resource=c("bed", "intensiveBed", "intensiveBedVentilation"))
res <- getDailyMaxResults( conf=conf, envs = y, fieldEvents = GABeds)
Now, simulated and real data are available in one single data frame: res
.
TODO: Measure Performance
getError <- function(res){ res1 <- res %>% filter(resource == "bed" & source == "babsim") df1 <- unique(data.frame(date = res1$date, x = res1$med)) res2 <- res %>% filter(resource == "bed" & source == "GA") df2 <- unique(data.frame(date = res2$date, x= res2$med)) dfBed <- full_join(df1, df2, by=c("date")) dfBed[is.na(dfBed)] <- 0 rmseBed <- rmse(dfBed[,2], dfBed[,3]) res1 <- res %>% filter(resource == "intensiveBed" & source == "babsim") df1 <- unique(data.frame(date = res1$date, x = res1$med)) res2 <- res %>% filter(resource == "intensiveBed" & source == "GA") df2 <- unique(data.frame(date = res2$date, x= res2$med)) dfIntensiveBed <- full_join(df1, df2, by=c("date")) dfIntensiveBed[is.na(dfIntensiveBed)] <- 0 rmseIntensiveBed <- rmse(dfIntensiveBed[,2], dfIntensiveBed[,3]) res1 <- res %>% filter(resource == "intensiveBedVentilation" & source == "babsim") df1 <- unique(data.frame(date = res1$date, x = res1$med)) res2 <- res %>% filter(resource == "intensiveBedVentilation" & source == "GA") df2 <- unique(data.frame(date = res2$date, x= res2$med)) dfIntensiveBedVentilation <- full_join(df1, df2, by=c("date")) dfIntensiveBedVentilation[is.na(dfIntensiveBedVentilation)] <- 0 rmseIntensiveBedVentilation <- rmse(dfIntensiveBedVentilation[,2], dfIntensiveBedVentilation[,3]) return(rmseBed + rmseIntensiveBed + rmseIntensiveBedVentilation) }
getError(conf=conf, res)
p <- plotDailyMaxResults(res) print(p)
ggplotly(p)
In contrast to the babsim simmer model, which uses the daily number of infections, the standard models calculate the number of \sick persons using a time window of size \amntDaysSickness days.
The number of infected people that require hospitalisation are calculated as follows:
Not every infected person requires hospitalization. The number of people, that have to go to the hospital is determined as follows: Only \infected people from the last \amntDaysSickness days are considered. These are labeled as \sick. Note the minus one in the calculation, because the current day counts as one of the \amntDaysSickness days.
amntDaysSickness = 20 Infs <- ex1InfectedDf$Infected sickPerDay <- slide_dbl(Infs , ~sum(.x), .before = (amntDaysSickness -1)) head(data.frame(day = 1:length(Infs), infected= Infs, sick = sickPerDay, ex1InfsCum = cumsum(Infs)))
knitr::kable(head(data.frame(day = 1:length(Infs), infected= Infs, sick = sickPerDay, ex1InfsCum = cumsum(Infs))))
p <- {plot( cumsum(Infs), type = "l", col="black", xlab = "days", ylab = "infected, sick") lines( 1:observedPeriod, Infs, col = "blue") lines( 1:observedPeriod, sickPerDay, col = "red") legend('topleft', lty = 1, c("infectedCum","infected", "sick"), col = c("black", "blue", "red")) }
For the standard models (OBK, Köln, and WHO) the following percentages, based on the number of \sick persons, were determined: \factorHospital, \factorIntensive, and \factorVentilation.
The number of patients that need to go to the hospital is based on the infected people from the last \amntDaysSickness days.
## Get numbers as estimated in excel table based on fixed coefficients getDataFromFixedNumbers <- function(factorHospital, factorIntensive, factorVentilation, sickPerDay, source){ date <- as.POSIXct(seq(as.Date(StartDate), as.Date(EndDate), by="days")) return( rbind( data.frame("resource" = "bed","time" = 1:length(sickPerDay), "med" = ( sickPerDay * factorHospital), "source" = source, "date" = date), data.frame("resource" = "intensiveBed","time" = 1:length(sickPerDay), "med" = ( sickPerDay * factorIntensive), "source" = source, "date" = date), data.frame("resource" = "intensiveBedVentilation","time" = 1:length(sickPerDay), "med" = ( sickPerDay * factorVentilation), "source" = source, "date" = date) ) ) }
err <- c() for (i in 1:15){ trajList <- babsimHospitalTrajectories(GammaShapeParameter = i/10 , control = babsimHospitalPara()) y <- babsimHospital(arrivalTimes = arrivalTimes , simRepeats = 100 , control = babsimHospitalPara() , trajList = trajList) res <- getDailyMaxResults( envs = y, fieldEvents = GABeds) err <- c(err,getError(res)) }
errOLD <- c(14.480660, 12.815926, 11.432739, 10.106963, 9.055230, 8.486424, 8.093233, 7.855100, 8.619063, 8.821263, 9.639260, 10.266499, 11.265664, 13.171530, 13.869897)
err <- c(14.654427, 13.418457, 11.827037, 10.962369, 9.486851, 8.965150, 8.272998, 7.771752, 8.017022, 8.544688, 9.035368, 9.875065, 10.331149, 11.202670, 12.220776)
plot( (1:15)/10, err, xlab="Gamma Shape Parameter")
para <- babsimHospitalPara() conf <- babsimToolsConf() conf$parallel <- FALSE y2 <- babsimHospital(arrivalTimes = arrivalTimes , conf = conf , para = para )
res2 <- getDailyMaxResults( conf=conf, envs = y2, fieldEvents = GABeds) getError(conf=conf, res2)
p <- plotDailyMaxResults(res2) print(p)
\bibliography{../bab-bibfiles/bartzAll.bib}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.