diff --git a/SimpleSocialDistanceModel.Rmd b/SimpleSocialDistanceModel.Rmd index e065346..1a40e5e 100644 --- a/SimpleSocialDistanceModel.Rmd +++ b/SimpleSocialDistanceModel.Rmd @@ -554,8 +554,8 @@ ggplot(data=filter(mydf, times<80)) + geom_line(aes(x=dates,y=(median+imports[1: mydf=getAllCasesbyDay2(newsol,times,nReps) ggplot(data=filter(mydf, times<80)) + geom_line(aes(x=dates,y=(median+imports[1:80])/N))+ geom_ribbon(aes(x=dates,ymin = (lower25+qpois(0.25,2))/N, ymax = (upper75+qpois(0.75,2))/N), alpha = 0.5,fill="chocolate2") + -geom_rect(aes(xmin=lubridate::ymd("2020-03-14")+15, - xmax=lubridate::ymd("2020-03-15")+60), +geom_rect(aes(xmin=lubridate::ymd("2020-03-12")+15, + xmax=lubridate::ymd("2020-03-12")+60), ymin=0, ymax=3e-4, fill='blue', alpha=.005) + theme_bw()+ylab("Fraction infectious") @@ -615,8 +615,8 @@ ggplot(data=filter(mydf, times<80)) + geom_line(aes(x=dates,y=(median+imports[1: mydf=getAllCasesbyDay2(newsol,times,nReps) ggplot(data=filter(mydf, times<80)) + geom_line(aes(x=dates,y=(median+imports[1:80])/N))+ geom_ribbon(aes(x=dates,ymin = (lower25+qpois(0.25,2))/N, ymax = (upper75+qpois(0.75,2))/N), alpha = 0.5,fill="chocolate2") + -geom_rect(aes(xmin=lubridate::ymd("2020-03-14")+15, - xmax=lubridate::ymd("2020-03-15")+76), +geom_rect(aes(xmin=lubridate::ymd("2020-03-12")+15, + xmax=lubridate::ymd("2020-03-12")+76), ymin=0, ymax=3e-4, fill='blue', alpha=.005) + theme_bw()+ylab("Fraction infectious") diff --git a/SimpleSocialDistanceModel.html b/SimpleSocialDistanceModel.html index e8a70df..93830b0 100644 --- a/SimpleSocialDistanceModel.html +++ b/SimpleSocialDistanceModel.html @@ -7,7 +7,6 @@ - @@ -270,6 +269,7 @@ } img { max-width:100%; + height: auto; } .tabbed-pane { padding-top: 12px; @@ -343,6 +343,18 @@ } + + @@ -391,7 +403,7 @@

A building block model without distancing

pars=list(N=N,D=5,R0=2.56,k1=1/4, k2=1,q=0 ) out = as.data.frame(ode(y= state, times=times, func=seiqrmodel, parms=pars))
ggplot(data=out, aes(x=times,y=I+E1+E2))+geom_line()
-

+

Social distancing : MODEL DEFINITION

@@ -446,7 +458,7 @@

Social distancing : MODEL DEFINITION

sdtiming=mysdtiming)) ggplot(data=filter(out1,time<90), aes(x=time, y=(E2+I+E2d+Id)))+geom_line() + geom_line(data=filter(out2,time<90), aes(x=time, y=(E2+I+E2d+Id)),color="blue") -

+

Uncertainty

@@ -491,14 +503,14 @@

Step 1: the baseline curve with no measures taken

ggplot(data=mydf) + geom_line(aes(x=dates,y=median/N))+ geom_ribbon(aes(x=dates,ymin = lower25/N, ymax = upper75/N), alpha = 0.5,fill="grey") + theme_bw()+ylab("Fraction infectious")+ylim(c(0,0.3)) -

+

Here is a plot showing the cumulative number who have been infected (this now includes those who are still in the incubation period)

N=bpars[[1]]$N
 mydf=filter(getEverInfbyDay(tt2[[1]],times,nReps), times<210)
 ggplot(data=mydf) + geom_line(aes(x=dates,y=median/N))+
   geom_ribbon(aes(x=dates,ymin = lower25/N, ymax = upper75/N), alpha = 0.5,fill="grey") +
   theme_bw()+ylab("Cumulative infected")+ylim(c(0,1))
-

+

Step 2

@@ -512,14 +524,14 @@

Step 2

ggplot(data=mydf) + geom_line(aes(x=dates,y=median/N))+ geom_ribbon(aes(x=dates,ymin = lower25/N, ymax = upper75/N), alpha = 0.5,fill="blue") + theme_bw()+ylab("Fraction infectious")+ylim(c(0,0.3)) -

+

Here are the cumulative numbers infected.

N=bpars[[1]]$N
 mydf=filter(getEverInfbyDay(tt2[[2]],times,nReps), times<210)
 ggplot(data=mydf) + geom_line(aes(x=dates,y=median/N))+
   geom_ribbon(aes(x=dates,ymin = lower25/N, ymax = upper75/N), alpha = 0.5,fill="blue") +
   theme_bw()+ylab("Cumulative infected")+ylim(c(0,1))
-

+

Step 3: Strong broad social distancing interventions

@@ -528,26 +540,26 @@

Step 3: Strong broad social distancing interventions

f = hh*1.45 + school*0.1 + work*0.35 + community*0.35 f
## [1] 0.6
-
N=bpars[[3]]$N # actually resetting N isn't necessary, but it's good practice
+
N=bpars[[3]]$N # actually resetting N isn't necessary, but it's good practice
 mydf=filter(getAllCasesbyDay2(tt2[[3]],times,nReps), times<260)
 ggplot(data=mydf) + geom_line(aes(x=dates,y=median/N))+
   geom_ribbon(aes(x=dates,ymin = lower25/N, ymax = upper75/N), alpha = 0.5,fill="green") +
   theme_bw()+ylab("Fraction infectious")+ylim(c(0,0.3))
-

+

And cumulative infected:

N=bpars[[1]]$N
 mydf=filter(getEverInfbyDay(tt2[[3]],times,nReps), times<260)
 ggplot(data=mydf) + geom_line(aes(x=dates,y=median/N))+
   geom_ribbon(aes(x=dates,ymin = lower25/N, ymax = upper75/N), alpha = 0.5,fill="green") +
   theme_bw()+ylab("Cumulative infected")+ylim(c(0,1))
-

+

Comparisons and the early phase

Here we show three social distancing scenarios on the same plot for comparison, and we show the early rise. In most of the above plots, it looks like there are no cases in the first few months, but this is misleading. It’s not that there are no cases, it’s just that the numbers grow so high later that we can’t see the rises in the early phase unless we zoom in on that time period.

ll=makePlots(tt2,type="all",PopScale = TRUE,popSize =pars$N)
 grid.arrange(ll[[1]], ll[[2]])
-

+

Step 4 what happens if social distancing is turned off at a fixed time?

@@ -558,7 +570,7 @@

Step 4 what happens if social distancing is turned off at a fixed time?

ggplot(data=mydf) + geom_line(aes(x=dates,y=median/N))+ geom_ribbon(aes(x=dates,ymin = lower25/N, ymax = upper75/N), alpha = 0.5,fill="purple") + theme_bw()+ylab("Fraction infectious")+ylim(c(0,0.3))
-

+

What if it is turned off at 100 days instead? (dark green fill, below).

new2=function(t) {ifelse( (t > 5 & t< 100),1, 0) }
 new2sol= multisolve(params=bpars[[3]],timing = new2, state,times, nReps = nReps)
@@ -568,7 +580,7 @@ 

Step 4 what happens if social distancing is turned off at a fixed time?

geom_line(data=mydf2, aes(x=dates,y=median/N))+ geom_ribbon(data=mydf2,aes(x=dates,ymin=lower25/N, ymax = upper75/N), alpha = 0.5,fill="darkgreen")+ theme_bw()+ylab("Fraction infectious")+ylim(c(0,0.3))
-

+

Step 5: “Planking” the curve

@@ -581,7 +593,7 @@

Step 5: “Planking” the curve

ggplot(data=mydf) + geom_line(aes(x=dates,y=(median)/N))+ geom_ribbon(aes(x=dates,ymin = (lower25+qpois(0.25,2))/N, ymax = (upper75+qpois(0.75,2))/N), alpha = 0.5,fill="chocolate2") + theme_bw()+ylab("Fraction infectious") #+ylim(c(0,0.3)) -

+

Step 5b Better than planking: suppression

Here, most of the population engages in strong social distancing. While household contact rates go up, community and workplace contacts fall to only 10% of their usual levels. If 1/5 of the contacts are household, and these increase by 50%, and the rest of the contacts are reduced to 10% of their baseline, we’d have \(f = (0.2(Raise) + 0.8(Fall))\) which is 0.34. This reduces the reproduction number to below 1, and cases fall. Case counts are now driven by the time lag (for 2-3 weeks we still see new cases appear, because they were infected before distancing measures took hold). Furthermore, sporadic cases enter from other areas, particularly if we re-open borders and other areas do not have as good control as we do (in this hypothetical scenario). Here, since we have no meaningful build-up of immunity, as soon as we scale back social distancing we see the same curves that we had above, but they happen later. We visualize stochastic importations (but it’s cheating a little). They aren’t transmitting in the model; since we know here that sustained transmission is not possible in this population, each importation will give rise to some small number of new cases; we use a Poisson distribution to visualize this.

@@ -593,7 +605,7 @@

Step 5b Better than planking: suppression

ggplot(data=mydf) + geom_line(aes(x=dates,y=(median+imports)/N))+ geom_ribbon(aes(x=dates,ymin = (lower25+qpois(0.25,3.5))/N, ymax = (upper75+qpois(0.75,3.5))/N), alpha = 0.5,fill="chocolate2") + theme_bw()+ylab("Fraction infectious") #+ylim(c(0,0.3)) -

+

And now what happens if the curve falls, people get complacent, and measures are relaxed?

newtime=function(t) {ifelse( (t > 5 & t< 60) ,1, 0) }
 strongpars = list(N=N,D=5,R0=2.5,k1=1/4, k2=1,q=0, r=1, ur=0.4, f=0.38)
@@ -603,12 +615,12 @@ 

Step 5b Better than planking: suppression

ggplot(data=filter(mydf, times<70)) + geom_line(aes(x=dates,y=(median+imports[1:70])/N))+ geom_ribbon(aes(x=dates,ymin = (lower25+qpois(0.25,2))/N, ymax = (upper75+qpois(0.75,2))/N), alpha = 0.5,fill="chocolate2") + theme_bw()+ylab("Fraction infectious") #+ylim(c(0,0.3))
-

+

Step 5c introduction of social distancing is slower

-

Here, social distancing takes place over a week with a linear decline in f.

+

Here, social distancing takes place over a week with a linear decline in f. 

socdist2 <- function(t,state,pars,sdprofile) {
   with(as.list(c(state,pars)), { 
 #    f = ifelse(sdtiming(t)==1, pars$f, 1) # if social distancing is on, use pars$f. Otherwise, f is 1.
@@ -669,16 +681,16 @@ 

Step 5c introduction of social distancing is slower

ggplot(data=filter(mydf, times<80)) + geom_line(aes(x=dates,y=(median+imports[1:80])/N))+ geom_ribbon(aes(x=dates,ymin = (lower25+qpois(0.25,2))/N, ymax = (upper75+qpois(0.75,2))/N), alpha = 0.5,fill="chocolate2") + theme_bw()+ylab("Fraction infectious") #+ylim(c(0,0.3))
-

+

mydf=getAllCasesbyDay2(newsol,times,nReps)
 ggplot(data=filter(mydf, times<80)) + geom_line(aes(x=dates,y=(median+imports[1:80])/N))+
   geom_ribbon(aes(x=dates,ymin = (lower25+qpois(0.25,2))/N, ymax = (upper75+qpois(0.75,2))/N), alpha = 0.5,fill="chocolate2") +
-geom_rect(aes(xmin=lubridate::ymd("2020-03-14")+15,
-                xmax=lubridate::ymd("2020-03-15")+60),
+geom_rect(aes(xmin=lubridate::ymd("2020-03-12")+15,
+                xmax=lubridate::ymd("2020-03-12")+60),
                   ymin=0, ymax=3e-4,
-            fill='blue', alpha=.005)  +
+            fill='blue', alpha=.005)  +
   theme_bw()+ylab("Fraction infectious") 
-

+

ANd now one where SD is not turned off

# now I just want f(t) as my timing function 
 
@@ -709,16 +721,16 @@ 

Step 5c introduction of social distancing is slower

ggplot(data=filter(mydf, times<80)) + geom_line(aes(x=dates,y=(median+imports[1:80])/N))+ geom_ribbon(aes(x=dates,ymin = (lower25+qpois(0.25,2))/N, ymax = (upper75+qpois(0.75,2))/N), alpha = 0.5,fill="chocolate2") + theme_bw()+ylab("Fraction infectious") #+ylim(c(0,0.3))
-

+

mydf=getAllCasesbyDay2(newsol,times,nReps)
 ggplot(data=filter(mydf, times<80)) + geom_line(aes(x=dates,y=(median+imports[1:80])/N))+
   geom_ribbon(aes(x=dates,ymin = (lower25+qpois(0.25,2))/N, ymax = (upper75+qpois(0.75,2))/N), alpha = 0.5,fill="chocolate2") +
-geom_rect(aes(xmin=lubridate::ymd("2020-03-14")+15,
-                xmax=lubridate::ymd("2020-03-15")+76),
+geom_rect(aes(xmin=lubridate::ymd("2020-03-12")+15,
+                xmax=lubridate::ymd("2020-03-12")+76),
                   ymin=0, ymax=3e-4,
-            fill='blue', alpha=.005)  +
+            fill='blue', alpha=.005)  +
   theme_bw()+ylab("Fraction infectious") 
-

+

Step 6: Smaller population and/or effect of unknown infections

@@ -737,7 +749,7 @@

Step 6: Smaller population and/or effect of unknown infections

ggplot(data=mydf) + geom_line(aes(x=dates,y=median/smallN))+ geom_ribbon(aes(x=dates,ymin = lower25/smallN, ymax = upper75/smallN), alpha = 0.5,fill="purple") + theme_bw()+ylab("Fraction infectious")#+ylim(c(0,0.3)) -

+

Unfortunately, a wider, flatter, curve is just a series of these little bumps, piling on one after the other, and on top of each other. Unless we really prevent the small sub-populations having any contact with each other, we are back to the wide, slow curves in models for bigger well-mixed populations. Whether China sees resurgence after normal activities resume will be interesting to see; it would require preventing imported cases.

@@ -768,23 +780,6 @@

Limitations and discussion

- - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +

To download data export for all scenario documented here, go to the Data Summary and Download section.

+
+

Scenario Results

+
+

Scenario 1: No Social Distancing

+
+

+Figure 1a: Infections over time for no social distancing +
+


+
+

+Figure 1b: Cumulative infections over time for no social distancing +
+


+
+
+

Scenario 2: Medium-scale Social Distancing

+

Example calculation of contact factor \(f\) for meidum-scale social distancing

+
hh=0.25; school=0.25*0.4; work=0.75*0.4; community=0.35; # portion contacts 
+f = hh*1 + school*0.9 + work*0.65 + community*0.75
+f
+
## [1] 0.7975
+
+

+Figure 2a: Infections over time for medium social distancing +
+


+
+

+Figure 2b: Cumulative infections over time for medium social distancing +
+


+
+
+

Scenario 3: Strong Broad Social Distancing

+

Example calculation of contact factor \(f\) for high-level social distancing

+
hh=0.25; school=0.25*0.4; work=0.75*0.4; community=0.35; # portion contacts 
+f = hh*1.45 + school*0.1 + work*0.35 + community*0.35
+f
+
## [1] 0.6
+
+

+Figure 3a: Infections over time for high-level social distancing +
+


+
+

+Figure 3b: Cumulative infections over time for high-level social distancing +
+


+
+
+

Comparisons and the early phase

+

Here we show three social distancing scenarios on the same plot for comparison, and we show the early rise. In most of the above plots, it looks like there are no cases in the first few months, but this is misleading. It’s not that there are no cases, it’s just that the numbers grow so high later that we can’t see the rises in the early phase unless we zoom in on that time period.

+

+
+
+

Scenario 4.1: Strong Broad Social distancing limited to 200 days

+
+

+Figure 4.1a: Infections over time for 200 days of high-level social distancing +
+


+
+

+Figure 4.1b: Cumulative infections over time for 200 days of high-level social distancing +
+


+
+
+

Scenario 4.2: Strong Broad Social distancing limited to 100 days

+
+

+Figure 4.2a: Infections over time for 100 days of high-level social distancing +
+


+
+

+Figure 4.2b: Cumulative infections over time for 100 days of high-level social distancing +
+


+
+
+

Scenario 5c1: Slow 45-day social distancing

+
+

+Figure 5c1a: Infections over time in the first 80 days for slow 45-day social distancing +
+


+
+

+

Figure 5c1b: Infections over time for slow 45-day social distancing in the longer term

+
+


+
+

+

Figure 5c1c: Cumulative infections over time for slow 45-day social distancing in the longer term

+
+


+
+
+

Scenario 5c2: Slow then very strong social distancing

+

Note: this scenario results in a peak of around 1,100 infections.

+
+

+Figure 5c2a: Infections over time for slow then very strong social distancing in the first 80 days +
+


+
+

+

Figure 5c2b: Infections over time for slow then very strong social distancing in the longer term

+
+


+
+

+

Figure 5c2c: Cumulative infections over time for slow then very strong social distancing in the longer term

+
+


+

Note: Scenario 5 “Planking” the curve or “supression” options have been excluded as they produce uncertain or unrealistic results. Scenario 6 on smaller population is excluded. To see these scenarios, go to the main model page.

+
+
+
+

Data Summary and Download

+
+

Summary of Assumptions and Results

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ScenarioAssumptionWhen Infection PeaksWhen Infection Stops*
Scenario 1: No Social Distancing• Factor of contact is f=1.0
• Social distancing measures are lifted only when infection stops or reaches population saturation
• COVID-19 Basic Reproduction Number (R0) has mean 2.5 and sd 0.25
• Start date of infection is 12-03-2020
• Population of 2.4 Million People
2020-052020-09
Scenario 2: Medium-scale Social Distancing• Factor of contact is f≈0.80
• Contacts break down: 25% household, 40% school/work, and 35% broader community
• Reduced contact due to preventative measure: school by 10%, work by 35%, community by 25%, household no change
• Social distancing measures are lifted only when infection stops or reaches population saturation
• COVID-19 Basic Reproduction Number (R0) follows a normal distribution with mean 2.5 and sd 0.25
• Start date of infection is 12-03-2020
• Population of 2.4 Million People
2020-072020-12
Scenario 3: Strong Broad Social Distancing• Factor of contact is f≈0.6
• Contacts break down: 25% household, 40% school/work, and 35% broader community
• Reduced contact due to preventative measure: school by 90%, work by 65%, community by 65%, household no change
• Social distancing measures are lifted only when infection stops or reaches population saturation
• COVID-19 Basic Reproduction Number (R0) follows a normal distribution with mean 2.5 and sd 0.25
• Start date of infection is 12-03-2020
• Population of 2.4 Million People
2020-082021-04
Scenario 4.1: Strong Broad Social distancing limited to 200 days• Factor of contact is f≈0.6
• Contacts break down: 25% household, 40% school/work, and 35% broader community
• Reduced contact due to preventative measure: school by 90%, work by 65%, community by 65%, household no change
• Social distancing measures are lifted after 200 days
• COVID-19 Basic Reproduction Number (R0) follows a normal distribution with mean 2.5 and sd 0.25
• Start date of infection is 12-03-2020
• Population of 2.4 Million People
2020-082021-04
Scenario 4.2: Strong Broad Social distancing limited to 100 days• Factor of contact is f≈0.6
• Contacts break down: 25% household, 40% school/work, and 35% broader community
• Reduced contact due to preventative measure: school by 90%, work by 65%, community by 65%, household no change
• Social distancing measures are lifted after 100 days
• COVID-19 Basic Reproduction Number (R0) follows a normal distribution with mean 2.5 and sd 0.25
• Start date of infection is 12-03-2020
• Population of 2.4 Million People
2020-072020-11
Scenario 5c1: Slow 45-day social distancing• Do nothing for the first 15 days
• Then implements very strong social distancing slowly, factor of contact decreases from f=1.0 to f=0.4 over 1 week
• Social distancing measures lifted at day 60 (45 days of social distancing)
• COVID-19 Basic Reproduction Number (R0) follows a normal distribution with mean 2.5 and sd 0.25
• Start date of infection is 12-03-2020
• Population of 2.4 Million People
2020-082021-01
Scenario 5c2: Slow then very strong social distancing✝• Do nothing for the first 15 days
• Then implements very strong social distancing slowly, factor of contact decreases from f=1.0 to f=0.4 over 1 week
• Social distancing measures are lifted only when infection stops or reaches population saturation
• COVID-19 Basic Reproduction Number (R0) follows a normal distribution with mean 2.5 and sd 0.25
• Start date of infection is 12-03-2020
• Population of 2.4 Million People
2020-032020-06
+

*Infection considered stopped when monthly infection falls below 100.
✝Scenario 5c2 is a outbreak prevented scenario where infection never reaches population saturation.

+
+

+

Figure 6: Cumulative infections over time for all scenarios (excl. scen5c2_slHiSocDist)

+
+


+
+
+

Download Daily Data

+

Download data export of cumulative infection by day for all scenarios: covid19_all_scen_daily.xlsx

+
+
+

Download Summary Data

+

Download data export of cumulative and new infection by month for all scenarios: covid19_all_scen_monthly.xlsx

+
+
+ + + + +
+ + + + + + + + diff --git a/data_output/covid19_all_scen_daily.xlsx b/data_output/covid19_all_scen_daily.xlsx new file mode 100644 index 0000000..ab33f26 Binary files /dev/null and b/data_output/covid19_all_scen_daily.xlsx differ diff --git a/data_output/covid19_all_scen_monthly.xlsx b/data_output/covid19_all_scen_monthly.xlsx new file mode 100644 index 0000000..43b53c3 Binary files /dev/null and b/data_output/covid19_all_scen_monthly.xlsx differ diff --git a/data_output/covid19_all_scen_monthly_BW.xlsx b/data_output/covid19_all_scen_monthly_BW.xlsx new file mode 100644 index 0000000..02ceb37 Binary files /dev/null and b/data_output/covid19_all_scen_monthly_BW.xlsx differ