## ----select-town,echo=FALSE---------------------------------------------------
TOWN <- "London"
## ----opts,include=FALSE,cache=FALSE-------------------------------------------
options(
keep.source=TRUE,
stringsAsFactors=FALSE,
encoding="UTF-8",
cores=4
)
set.seed(998468235L,kind="L'Ecuyer")
mcopts <- list(preschedule=FALSE,set.seed=TRUE)
library(ggplot2)
theme_set(theme_bw())
## ----pomp-install,eval=FALSE--------------------------------------------------
## library(devtools)
## install_github("kingaa/pomp")
## ----prelims,cache=FALSE------------------------------------------------------
set.seed(594709947L)
library(tidyverse)
library(pomp)
## ----load-data----------------------------------------------------------------
load("twentycities.rda")
measles |>
mutate(year=as.integer(format(date,"%Y"))) |>
filter(town==TOWN & year>=1950 & year<1964) |>
mutate(time=(julian(date,origin=as.Date("1950-01-01")))/365.25+1950) |>
filter(time>1950 & time<1964) |>
select(time,cases) -> dat
demog |> filter(town==TOWN) |>
select(-town) -> demog
## ----data-plot----------------------------------------------------------------
dat |> ggplot(aes(x=time,y=cases))+geom_line()
demog |>
pivot_longer(-year) |>
ggplot(aes(x=year,y=value))+geom_point()+
facet_wrap(~name,ncol=1,scales="free_y")
## ----prep-covariates----------------------------------------------------------
demog |>
reframe(
time=seq(from=min(year),to=max(year),by=1/12),
pop=predict(smooth.spline(x=year,y=pop),x=time)$y,
birthrate=predict(smooth.spline(x=year+0.5,y=births),x=time-4)$y
) -> covar
## ----covarplot----------------------------------------------------------------
plot(pop~time,data=covar,type='l')
points(pop~year,data=demog)
plot(birthrate~time,data=covar,type='l')
points(births~year,data=demog)
plot(birthrate~I(time-4),data=covar,type='l')
points(births~I(year+0.5),data=demog)
## ----rprocess-----------------------------------------------------------------
rproc <- Csnippet("
double beta, br, seas, foi, dw, births;
double rate[6], trans[6];
// cohort effect
if (fabs(t-floor(t)-251.0/365.0) < 0.5*dt)
br = cohort*birthrate/dt + (1-cohort)*birthrate;
else
br = (1.0-cohort)*birthrate;
// term-time seasonality
t = (t-floor(t))*365.25;
if ((t>=7&&t<=100) || (t>=115&&t<=199) || (t>=252&&t<=300) || (t>=308&&t<=356))
seas = 1.0+amplitude*0.2411/0.7589;
else
seas = 1.0-amplitude;
// transmission rate
beta = R0*seas*(1.0-exp(-(gamma+mu)*dt))/dt;
// force of infection
foi = beta*pow(I+iota,alpha)/pop;
// white noise (extra-demographic stochasticity)
dw = rgammawn(sigmaSE,dt);
rate[0] = foi*dw/dt; //infection rate (stochastic)
rate[1] = mu; // natural S death
rate[2] = sigma; // rate of ending of latent stage
rate[3] = mu; // natural E death
rate[4] = gamma; // recovery
rate[5] = mu; // natural I death
// Poisson births
births = rpois(br*dt);
// transitions between classes
reulermultinom(2,S,&rate[0],dt,&trans[0]);
reulermultinom(2,E,&rate[2],dt,&trans[2]);
reulermultinom(2,I,&rate[4],dt,&trans[4]);
S += births - trans[0] - trans[1];
E += trans[0] - trans[2] - trans[3];
I += trans[2] - trans[4] - trans[5];
W += (dw - dt)/sigmaSE; // standardized i.i.d. white noise
C += trans[4]; // true incidence
")
## ----initializer--------------------------------------------------------------
rinit <- Csnippet("
double m = pop/(S_0+E_0+I_0+R_0);
S = nearbyint(m*S_0);
E = nearbyint(m*E_0);
I = nearbyint(m*I_0);
W = 0;
C = 0;
")
## ----dmeasure-----------------------------------------------------------------
dmeas <- Csnippet("
double m = rho*C;
double v = m*(1.0-rho+psi*psi*m);
double tol = 1.0e-18;
if (cases > 0.0) {
lik = pnorm(cases+0.5,m,sqrt(v)+tol,1,0)-pnorm(cases-0.5,m,sqrt(v)+tol,1,0)+tol;
} else {
lik = pnorm(cases+0.5,m,sqrt(v)+tol,1,0)+tol;
}
if (give_log) lik = log(lik);
")
## ----rmeasure-----------------------------------------------------------------
rmeas <- Csnippet("
double m = rho*C;
double v = m*(1.0-rho+psi*psi*m);
double tol = 1.0e-18;
cases = rnorm(m,sqrt(v)+tol);
if (cases > 0.0) {
cases = nearbyint(cases);
} else {
cases = 0.0;
}
")
## ----pomp-construction--------------------------------------------------------
dat |>
pomp(t0=with(dat,2*time[1]-time[2]),
time="time",
rprocess=euler(rproc,delta.t=1/365.25),
dmeasure=dmeas,
rmeasure=rmeas,
rinit=rinit,
partrans=parameter_trans(
log=c("mu","sigma","gamma","alpha","iota","psi","sigmaSE","R0"),
logit=c("rho","cohort","amplitude"),
barycentric=c("S_0","E_0","I_0","R_0")
),
covar=covariate_table(covar,times="time"),
accumvars=c("C","W"),
statenames=c("S","E","I","C","W"),
paramnames=c("R0","mu","sigma","gamma","alpha","iota",
"rho","sigmaSE","psi","cohort","amplitude",
"S_0","E_0","I_0","R_0")
) -> m1
## ----plot-pomp----------------------------------------------------------------
m1 |>
as.data.frame() |>
pivot_longer(-time) |>
ggplot(aes(x=time,y=value))+
geom_line()+
facet_grid(name~.,scales="free_y")
## ----load-mle,echo=FALSE------------------------------------------------------
read.csv(text="
town,loglik,loglik.sd,mu,delay,sigma,gamma,rho,R0,amplitude,alpha,iota,cohort,psi,S_0,E_0,I_0,R_0,sigmaSE
Bedwellty,-1125.1,0.14,0.02,4,57.9,146,0.311,24.7,0.16,0.937,0.0396,0.351,0.951,0.0396,2.64e-05,2.45e-05,0.96,0.0611
Birmingham,-3239.3,1.55,0.02,4,45.6,32.9,0.544,43.4,0.428,1.01,0.343,0.331,0.178,0.0264,8.96e-05,0.000335,0.973,0.0611
Bradford,-2586.6,0.68,0.02,4,45.6,129,0.599,32.1,0.236,0.991,0.244,0.297,0.19,0.0365,7.41e-06,4.59e-06,0.964,0.0451
Bristol,-2681.6,0.5,0.02,4,64.3,82.6,0.626,26.8,0.203,1.01,0.441,0.344,0.201,0.0358,9.62e-06,5.37e-06,0.964,0.0392
Cardiff,-2364.9,0.73,0.02,4,39,143,0.602,34.4,0.223,0.996,0.141,0.267,0.27,0.0317,1.01e-05,9.21e-06,0.968,0.0539
Consett,-1362.9,0.73,0.02,4,42.6,172,0.65,35.9,0.2,1.01,0.0731,0.31,0.406,0.0322,1.83e-05,1.97e-05,0.968,0.0712
Dalton.in.Furness,-726.1,0.3,0.02,4,73.6,257,0.455,28.3,0.203,0.989,0.0386,0.421,0.818,0.0387,2.23e-05,2.36e-05,0.961,0.0779
Halesworth,-318.6,0.51,0.02,4,49.6,210,0.754,33.1,0.381,0.948,0.00912,0.547,0.641,0.0526,1.99e-05,2.82e-05,0.947,0.0748
Hastings,-1583.7,0.21,0.02,4,56.3,74.1,0.695,34.2,0.299,1,0.186,0.329,0.396,0.0233,5.61e-06,3.4e-06,0.977,0.0955
Hull,-2729.4,0.39,0.02,4,42.1,73.9,0.582,38.9,0.221,0.968,0.142,0.275,0.256,0.0371,1.2e-05,1.13e-05,0.963,0.0636
Leeds,-2918.6,0.23,0.02,4,40.7,35.1,0.666,47.8,0.267,1,1.25,0.592,0.167,0.0262,6.04e-05,3e-05,0.974,0.0778
Lees,-548.1,1.1,0.02,4,45.6,244,0.612,29.7,0.153,0.968,0.0311,0.648,0.681,0.0477,2.66e-05,2.08e-05,0.952,0.0802
Liverpool,-3403.1,0.34,0.02,4,49.4,39.3,0.494,48.1,0.305,0.978,0.263,0.191,0.136,0.0286,0.000184,0.00124,0.97,0.0533
London,-3804.9,0.16,0.02,4,28.9,30.4,0.488,56.8,0.554,0.976,2.9,0.557,0.116,0.0297,5.17e-05,5.14e-05,0.97,0.0878
Manchester,-3250.9,0.66,0.02,4,34.4,56.8,0.55,32.9,0.29,0.965,0.59,0.362,0.161,0.0489,2.41e-05,3.38e-05,0.951,0.0551
Mold,-296.5,0.25,0.02,4,67.4,301,0.131,21.4,0.271,1.04,0.0145,0.436,2.87,0.064,2.61e-05,2.27e-05,0.936,0.0544
Northwich,-1195.1,2.25,0.02,4,45.6,147,0.795,30.1,0.423,0.948,0.0602,0.236,0.402,0.0213,1.32e-05,1.58e-05,0.979,0.0857
Nottingham,-2703.5,0.53,0.02,4,70.2,115,0.609,22.6,0.157,0.982,0.17,0.34,0.258,0.05,1.36e-05,1.41e-05,0.95,0.038
Oswestry,-696.1,0.49,0.02,4,37.3,168,0.631,52.9,0.339,1.04,0.0298,0.263,0.476,0.0218,1.56e-05,1.61e-05,0.978,0.0699
Sheffield,-2810.7,0.21,0.02,4,54.3,62.2,0.649,33.1,0.313,1.02,0.853,0.225,0.175,0.0291,6.04e-05,8.86e-05,0.971,0.0428
",stringsAsFactors=FALSE) -> mles
## ----mle----------------------------------------------------------------------
mles |> filter(town==TOWN) -> mle
paramnames <- c("R0","mu","sigma","gamma","alpha","iota",
"rho","sigmaSE","psi","cohort","amplitude",
"S_0","E_0","I_0","R_0")
theta <- unlist(mle[paramnames])
## ----mle-table,echo=FALSE-----------------------------------------------------
library(knitr)
kable(subset(mle,select=-c(town,mu,loglik.sd,delay,S_0,E_0,I_0,R_0)),row.names=FALSE)
## ----pfilter1-----------------------------------------------------------------
library(doFuture)
library(doRNG)
library(circumstance)
registerDoFuture()
registerDoRNG(998468235L)
plan(multicore)
m1 |>
pfilter(params=theta,Np=10000,Nrep=8) |>
logLik() |>
logmeanexp(se=TRUE,ess=TRUE)
## ----sims1,fig.height=8-------------------------------------------------------
m1 |>
simulate(params=theta,nsim=9,format="d",include.data=TRUE) |>
ggplot(aes(x=time,y=cases,group=.id,color=(.id=="data")))+
guides(color="none")+
geom_line()+facet_wrap(~.id,ncol=2)
## ----sims2--------------------------------------------------------------------
m1 |>
simulate(params=theta,nsim=200,format="d",include.data=TRUE) |>
select(time,.id,cases) |>
mutate(
data=if_else(.id=="data","data","simulation")
) |>
group_by(time,data) |>
reframe(
p=c("lo","med","hi"),
q=quantile(cases,prob=c(0.05,0.5,0.95),names=FALSE)
) |>
pivot_wider(names_from=p,values_from=q) |>
ggplot(aes(x=time,y=med,color=data,fill=data,ymin=lo,ymax=hi))+
geom_ribbon(alpha=0.2)