Learn R Programming

surveillance (version 1.5-4)

twinstim: Fit a Two-Component Spatio-Temporal Conditional Intensity Model

Description

A twinstim model as described in Meyer et al. (2012) is fitted to marked spatio-temporal point process data. This constitutes a regression approach for conditional intensity function modelling.

Usage

twinstim(endemic, epidemic, siaf, tiaf, qmatrix = data$qmatrix, data,
         subset, t0 = data$stgrid$start[1], T = tail(data$stgrid$stop,1),
         na.action = na.fail, start = NULL, partial = FALSE,
         control.siaf = list(F = list(), Deriv = list()),
         optim.args = list(), finetune = FALSE,
         model = FALSE, cumCIF = TRUE, cumCIF.pb = TRUE, verbose = TRUE)

Arguments

endemic
right-hand side formula for the exponential (Cox-like multiplicative) endemic component. May contain offsets (to be marked by the special function offset). If omitted or ~0 there will be no endemic component in the m
epidemic
formula representing the epidemic model for the event-specific covariates (marks) determining infectivity. Offsets are not implemented here. If omitted or ~0 there will be no epidemic component in the model.
siaf
spatial interaction function. May be NULL or missing (corresponding to siaf.constant(), i.e. constant infectivity independent of the spatial distance from the host), a list (specifying a continuous kernel, as e.g., r
tiaf
temporal interaction function. May be NULL (or missing, corresponding to constant infectivity independent of the temporal distance from the host), a list (specifying a continuous function, as e.g., returned by
qmatrix
square indicator matrix (0/1 or FALSE/TRUE) for possible transmission between the event types. The matrix will be internally converted to logical. Defaults to the $Q$ matrix specified in data
data
an object of class "epidataCS".
subset
an optional vector evaluating to logical indicating a subset of data$events to keep. Missing values are taken as FALSE. The expression is evaluated in the context of the data$events@data data.frame<
t0, T
events having occured during (-Inf;t0] are regarded as part of the prehistory $H_0$ of the process. Only events that occured in the interval (t0; T] are considered in the likelihood. The time point t0 (T) must be
na.action
how to deal with missing values in data$events? Do not use na.pass. Missing values in the spatio-temporal grid data$stgrid are not accepted.
start
a named vector of initial values for (a subset of) the parameters. The names must conform to the conventions of twinstim to be assigned to the correct model terms. For instance, "h.(Intercept)" = endemic intercept,
partial
logical indicating if a partial likelihood similar to the approach by Diggle et al. (2010) should be used (default is FALSE). Note that the partial likelihood implementation is not well tested.
control.siaf
a list with elements "F" and "Deriv", which are lists of extra arguments passed to the functions siaf$F and siaf$Deriv, respectively. These arguments mainly determine the accuracy of the numerica
optim.args
an argument list passed to optim, or NULL, in which case no optimization will be performed but the necessary functions will be returned in a list (similar to what is returned if
finetune
logical indicating if a second maximisation should be performed with robust Nelder-Mead optim using the resulting parameters from the first maximisation as starting point. This argument is only considered if partial = FALSE<
model
logical. If TRUE the result contains an element functions with the log-likelihood function (or partial log-likelihood function, if partial = TRUE), and optionally the score and the expected Fisher informa
cumCIF
logical (default: TRUE) indicating whether to calculate the fitted cumulative ground intensity at event times. This is the residual process, see residuals.twinstim.
cumCIF.pb
logical indicating if a progress bar should be shown during the calculation of cumCIF. Defaults to TRUE.
verbose
logical indicating if information should be printed during execution. Defaults to TRUE.

Value

  • Returns an S3 object of class "twinstim", which is a list with the following components:
  • coefficientsvector containing the MLE.
  • loglikvalue of the log-likelihood function at the MLE with a logical attribute "partial" indicating if the partial likelihood was used.
  • countsnumber of log-likelihood and score evaluations during optimization.
  • control.siafsee the Arguments section above.
  • optim.argsinput optimizer arguments used to determine the MLE.
  • convergedlogical indicating if the optimizer converged.
  • fisherinfoexpected Fisher information evaluated at the MLE. Only part of the output for full likelihood inference (partial = FALSE) and if spatial and temporal interaction functions are provided with their derivatives.
  • fisherinfo.observedobserved Fisher information matrix evaluated at the value of the MLE. Obtained as the negative Hessian. This is only part of the result if optim.args$method is not "nlminb" and if it was requested by setting hessian=TRUE in optim.args.
  • fittedfitted values of the conditional intensity function at the events.
  • fittedComponentstwo-column matrix with columns "h" and "e" containing the fitted values of the endemic and epidemic components, respectively. (Note that rowSums(fittedComponents) == fitted.)
  • taufitted cumulative ground intensities at the event times. Only calculated and returned if cumCIF = TRUE. This is the residual process of the model, see residuals.twinstim.
  • R0estimated basic reproduction number for each event. This equals the spatio-temporal integral of the epidemic intensity over the observation domain (t0;T] x W for each event.
  • nparsvector describing the lengths of the 5 parameter subvectors: endemic intercept(s) $\beta_0(\kappa)$, endemic coefficients $\beta$, epidemic coefficients $\gamma$, parameters of the siaf kernel, and parameters of the tiaf kernel.
  • qmatrixthe qmatrix associated with the epidemic data as supplied in the model call.
  • bboxthe bounding box of data$W.
  • timeRangethe time range used for fitting: c(t0,T).
  • formulaa list containing the four main parts of the model specification: endemic, epidemic, siaf, and tiaf.
  • functionsif model=TRUE this is a list with components ll, sc and fi, which are functions evaluating the log-likelihood, the score function and the expected Fisher information for a parameter vector $\theta$. The environment of these function is the model environment, which is thus retained in the workspace if model=TRUE.
  • callthe matched call.
  • runtimecontains the proc.time queried time taken to fit the model.
  • If model=TRUE, the model evaluation environment is assigned to this list and can thus be queried by calling environment() on the result.

encoding

latin1

Details

The function performs maximum likelihood inference for the additive-multiplicative spatio-temporal intensity model described in Meyer et al. (2012). It uses nlminb as the default optimizer and returns an object of class twinstim. Such objects have print, plot and summary methods. The output of the summary can be processed by the toLatex function. Furthermore, the usual model fit methods such as coef, vcov, logLik, residuals, and update are implemented. A specific add-on is the use of the functions R0 and simulate.

References

Diggle, P. J., Kaimi, I. & Abellana, R. (2010): Partial-likelihood analysis of spatio-temporal point-process data. Biometrics, 66, 347-354.

Martinussen, T. and Scheike, T. H. (2006): Dynamic Regression Models for Survival Data. Springer. Meyer, S., Elias, J. and H{oe}hle, M. (2012): A space-time conditional intensity model for invasive meningococcal disease occurrence. Biometrics, 68, 607-616. DOI-Link: http://dx.doi.org/10.1111/j.1541-0420.2011.01684.x Meyer, S. (2010): Spatio-Temporal Infectious Disease Epidemiology based on Point Processes. Master's Thesis, Ludwig-Maximilians-Universit{ae}t M{ue}nchen. Available as http://epub.ub.uni-muenchen.de/11703/

Rathbun, S. L. (1996): Asymptotic properties of the maximum likelihood estimator for spatio-temporal point processes. Journal of Statistical Planning and Inference, 51, 55-74.

See Also

twinSIR for a discrete space alternative. There is also a simulate.twinstim method, which simulates the point process based on the fitted twinstim.

Examples

Run this code
# Load invasive meningococcal disease data
data("imdepi")

### first, fit a simple endemic-only model

## Calculate initial value for the endemic intercept (the crude estimate
## which is used by default if no initial value is supplied).
## Assume the model only had a single-cell endemic component
## (rate of homogeneous Poisson process scaled for population density):
popdensity.overall <- with(subset(imdepi$stgrid, BLOCK == 1),
    weighted.mean(popdensity, area))
popdensity.overall   # pop. density in Germany is ~230 inhabitants/km^2
W.area <- with(subset(imdepi$stgrid, BLOCK == 1), sum(area))
W.area               # area of Germany is about 357100 km^2
# this should actually be the same as
sum(sapply(imdepi$W@polygons, slot, "area"))
# which here is not exactly the case because of polygon simplification

## initial value for the endemic intercept
h.intercept <- with(summary(imdepi),
    log(nEvents/popdensity.overall/diff(timeRange)/W.area))

## fit the endemic-only model
m_noepi <- twinstim(
    endemic = ~ 1 + offset(log(popdensity)) + I(start/365) +
                sin(start * 2 * pi/365) + cos(start * 2 * pi/365),
    data = imdepi, subset = !is.na(agegrp),
    optim.args = list(par=c(h.intercept,rep(0,3)), # this is the default
                      method="nlminb", control = list(trace=1)),
    model = FALSE, cumCIF = FALSE   # for reasons of speed
)

## look at the model summary
summary(m_noepi)


if (surveillance.options("allExamples"))
{
  ## type-dependent endemic intercept?
  m_noepi_type <- update(m_noepi, endemic = ~(1|type) + .)
  summary(m_noepi_type)
  
  # LR-test for a type-dependent intercept in the endemic-only model
  pchisq(2*(logLik(m_noepi_type)-logLik(m_noepi)), df=1, lower.tail=FALSE)
}


### add an epidemic component with just the intercept, i.e.
### assuming uniform dispersal in time and space up to a distance of
### eps.s = 200 km and eps.t = 30 days (see summary(imdepi))

m0 <- update(m_noepi, epidemic=~1, start=c("e.(Intercept)"=-18), model=TRUE)

## NOTE: in contrast to using nlminb() optim's BFGS would miss the
##       likelihood maximum wrt the epidemic intercept if starting at -10
m0_BFGS <- update(m_noepi, epidemic=~1, start=c("e.(Intercept)"=-10),
                  optim.args = list(method="BFGS"))
format(cbind(coef(m0), coef(m0_BFGS)), digits=3, scientific=FALSE)
m0_BFGS$fisherinfo   # singular Fisher information matrix here
m0$fisherinfo
logLik(m0_BFGS)
logLik(m0)
## nlminb is more powerful since we make use of the analytical fisherinfo
## as estimated by the model during optimization, which optim cannot

## summarize the model fit
s <- summary(m0, correlation = TRUE, symbolic.cor = TRUE)
s
# output the table of coefficients as LaTeX code
toLatex(s, digits=2, withAIC=FALSE)

## the default confint-method can be used for Wald-CI's
confint(m0, level=0.95)

## same R0 estimate for every event (epidemic intercept only)
summary(R0(m0, trimmed=FALSE))

## plot the path of the fitted total intensity
plot(m0, "total intensity", tgrid=500)

if (surveillance.options("allExamples"))
{
  ## extract "residual process" integrating over space (takes some seconds)
  res <- residuals(m0)
  # if the model describes the true CIF well _in the temporal dimension_,
  # then this residual process should behave like a stationary Poisson
  # process with intensity 1
  plot(res, type="l"); abline(h=c(0, length(res)), lty=2)
  # -> use the function checkResidualProcess
  checkResidualProcess(m0)

  ## NB: the model fit environment is kept in the workspace with model=TRUE
  sort(sapply(environment(m0), object.size))
  # saving m0 to RData will include this model environment, thus might
  # consume quiet a lot of disk space (as it does use memory), mainly
  # depending on the size of "stgrid", the number of "events" and the
  # polygonal resolution of "W"
}


if (surveillance.options("allExamples"))
{
  ### try with spatially decreasing interaction kernel
  ## Likelihood evaluation takes much longer than for constant spatial spread
  ## Here we use the kernel of an isotropic bivariate Gaussian with same
  ## standard deviation for both finetypes

  m1 <- update(m0,
      siaf = siaf.gaussian(1, F.adaptive = TRUE),
      start = c("e.siaf.1" = 2.8),  # exp(2.8) = sigma = 16 km
      optim.args = list(fixed="e.siaf.1"),
                        # for reasons of speed of the example, the siaf
                        # parameter log(sigma) is fixed to 2.8 here
      control.siaf = list(F=list(adapt=0.25)) # use adaptive eps=sigma/4
  )

  AIC(m_noepi, m0, m1)   # further improvement
  summary(m1, test.iaf=FALSE)   # nonsense to test H0: log(sigma) = 0
  plot(m1, "siaf", xlim=c(0,200), types=1)   # the same for types=2


  ### add epidemic covariates

  m2 <- update(m1, epidemic = ~ 1 + type + agegrp)
  
  AIC(m1, m2)   # further improvement
  summary(m2)
  
  # look at estimated R0 values by event type
  tapply(R0(m2), imdepi$events@data[names(R0(m2)), "type"], summary)
}

Run the code above in your browser using DataLab