The most popular model to model epidemics is the so-called SIR model – or Kermack-McKendrick. Consider a population of size N, and assume that S is the number of susceptible, I the number of infectious, and R for the number recovered (or immune) individuals, \displaystyle {\begin{aligned}&{\frac {dS}{dt}}=-{\frac {\beta IS}{N}},\\[6pt]&{\frac {dI}{dt}}={\frac {\beta IS}{N}}-\gamma I,\\[6pt]&{\frac {dR}{dt}}=\gamma I,\end{aligned}}so that \displaystyle{{\frac{dS}{dt}}+{\frac {dI}{dt}}+{\frac {dR}{dt}}=0}which implies that S+I+R=N. In order to be more realistic, consider some (constant) birth rate \mu, so that the model becomes\displaystyle {\begin{aligned}&{\frac {dS}{dt}}=\mu(N-S)-{\frac {\beta IS}{N}},\\[6pt]&{\frac {dI}{dt}}={\frac {\beta IS}{N}}-(\gamma+\mu) I,\\[6pt]&{\frac {dR}{dt}}=\gamma I-\mu R,\end{aligned}}Note, in this model, that people get sick (infected) but they do not die, they recover. So here, we can model chickenpox, for instance, not SARS.
The dynamics of the infectious class depends on the following ratio:\displaystyle{R_{0}={\frac {\beta }{\gamma +\mu}}} which is the so-called basic reproduction number (or reproductive ratio). The effective reproductive ratio is R_0S/N, and the turnover of the epidemic happens exactly when R_0S/N=1, or when the fraction of remaining susceptibles is R_0^{-1}. As shown in Directly transmitted infectious diseases:Control by vaccination, if S/N<R_0^{-1} the disease (the number of people infected) will start to decrease.
Want to see it ? Start with
mu = 0 beta = 2 gamma = 1/2 |
for the parameters. Here, R_0=4. We also need starting values
epsilon = .001 N = 1 S = 1-epsilon I = epsilon R = 0 |
Then use the ordinary differential equation solver, in R. The idea is to say that \boldsymbol{Z}=(S,I,R) and we have the gradient \frac{\partial \boldsymbol{Z}}{\partial t} = SIR(\boldsymbol{Z})where SIR is function of the various parameters. Hence, set
p = c(mu = 0, N = 1, beta = 2, gamma = 1/2) start_SIR = c(S = 1-epsilon, I = epsilon, R = 0) |
The we must define the time, and the function that returns the gradient,
times = seq(0, 10, by = .1) SIR = function(t,Z,p){ S=Z[1]; I=Z[2]; R=Z[3]; N=S+I+R mu=p["mu"]; beta=p["beta"]; gamma=p["gamma"] dS=mu*(N-S)-beta*S*I/N dI=beta*S*I/N-(mu+gamma)*I dR=gamma*I-mu*R dZ=c(dS,dI,dR) return(list(dZ))} |
To solve this problem use
library(deSolve) resol = ode(y=start_SIR, times=times, func=SIR, parms=p) |
We can visualize the dynamics below
par(mfrow=c(1,2)) t=resol[,"time"] plot(t,resol[,"S"],type="l",xlab="time",ylab="") lines(t,resol[,"I"],col="red") lines(t,resol[,"R"],col="blue") plot(t,t*0+1,type="l",xlab="time",ylab="",ylim=0:1) polygon(c(t,rev(t)),c(resol[,"R"],rep(0,nrow(resol))),col="blue") polygon(c(t,rev(t)),c(resol[,"R"]+resol[,"I"],rev(resol[,"R"])),col="red") |
We can actually also visualize the effective reproductive number is R_0S/N, where
R0=p["beta"]/(p["gamma"]+p["mu"]) |
The effective reproductive number is on the left, and as we mentioned above, when we reach 1, we actually reach the maximum of the infected,
plot(t,resol[,"S"]*R0,type="l",xlab="time",ylab="") abline(h=1,lty=2,col="red") abline(v=max(t[resol[,"S"]*R0>=1]),col="darkgreen") points(max(t[resol[,"S"]*R0>=1]),1,pch=19) plot(t,resol[,"S"],type="l",xlab="time",ylab="",col="grey") lines(t,resol[,"I"],col="red",lwd=3) lines(t,resol[,"R"],col="light blue") abline(v=max(t[resol[,"S"]*R0>=1]),col="darkgreen") points(max(t[resol[,"S"]*R0>=1]),max(resol[,"I"]),pch=19) |
And when adding a \mu parameter, we can obtain some interesting dynamics on the number of infected,
times = seq(0, 100, by=.1) p = c(mu = 1/100, N = 1, beta = 50, gamma = 10) start_SIR = c(S=0.19, I=0.01, R = 0.8) resol = ode(y=start_SIR, t=times, func=SIR, p=p) plot(resol[,"time"],resol[,"I"],type="l",xlab="time",ylab="") |
OpenEdition suggests that you cite this post as follows:
Arthur Charpentier (March 19, 2020). Modeling pandemics (1). Freakonometrics. Retrieved September 16, 2024 from https://doi.org/10.58079/oveu
I have problems with the graphics of the SIR model
the script line:
> abline(v=max(t[resol[,”S”]*R0>=1]),col=”darkgreen”)
Generates the following error:
Error: unexpected ‘;’ in “abline(v=max(t[resol[,”S”]*R0>”
Tne next script line is the same problem:
> points(max(t[resol[,”S”]*R0>=1]),1,pch=19)
Error: unexpected ‘;’ in “points(max(t[resol[,”S”]*R0>”
Ca you help to understand and resolve this?
I think you just need to replace “>” with a greater-than sign: “>”
I have some issues with the editor.. sorry