spatiotemporal model with dynamic covariates

97 views
Skip to first unread message

Moritz Klaassen

unread,
Mar 11, 2025, 11:38:22 AM3/11/25
to R-inla discussion group

Hi folks,

I'm working on a marine integrated species distribution model (ISDM) using inlabru and the PointedSDMs wrapper. My model combines two data sources:

  • Presence-Only (PO) Data:
    Collected over 12 months, this dataset is highly spatially biased but provides valuable temporal information on dynamic covariates (temperature).

  • Presence-Absence (PA) Data:
    Derived from a survey (1 month)  with good spatial coverage, providing static covariates such as bathymetry and slope.

My goal is to build an integrated model that incorporates bathymetry and slope from the PA data and temperature from the PO data, in which I want to model PO as an IPP and PA Binomial. To test whether the model can capture the dynamic distribution driven by temperature variations, I’m currently focusing on modelling only the PO data.

In my workflow, I define the temporal component by including a "month" variable in the PO dataset. In the startISDM() call, I specify the temporal variable as follows:

organizedData_PO <- startISDM(
  data = po_sf,
  Mesh = mesh,
  Projection = proj_azores,
  spatialCovariates = env_stack_bst_masked,  
  Boundary = boundary_inner_PO,
  responseCounts = "counts",
  pointsSpatial = "individual",
  temporalName = "month"
)

For temperature, I combine the 12 monthly layers into a dynamic component using changeComponents(): (I also use a 1D SPDE for temperature to capture a non linear response)

organizedData_PO$changeComponents(
  "temperature(
     main = I(
      (month == 1)*temperature_month1 +
      (month == 2)*temperature_month2 +
      (month == 3)*temperature_month3 +
      (month == 4)*temperature_month4 +
      (month == 5)*temperature_month5 +
      (month == 6)*temperature_month6 +
      (month == 7)*temperature_month7 +
      (month == 8)*temperature_month8 +
      (month == 9)*temperature_month9 +
      (month == 10)*temperature_month10 +
      (month == 11)*temperature_month11 +
      (month == 12)*temperature_month12
     ),
     model = INLA::inla.spde2.pcmatern(
       mesh = fmesher::fm_mesh_1d(
         loc      = seq(-2, 2, length.out = 20),
         boundary = 'free'
       ),
       alpha       = 2,
       prior.range = c(1, 0.05),
       prior.sigma = c(1, 0.05),
       constr      = TRUE
     )
  )"
)

However, I'm not entirely sure if this is the most elegant or robust way to link the temporal "month" variable from the PO sf to the dynamic temperature SPDE fields. I am wondering:

  • Is specifying temporalName = "month" in startISDM() sufficient for linking the month-specific temperature layers to the PO data? (this question might be limited to users of the package)
  • Are there any resources or example cases available where others have used temporally changing covariates in spatiotemporal models in INLA? (I am aware of a few examples using spatiotemporal models but not with temporally explicit covariates)

Lastly, while I am working in the PointedSDMs package, I would also appreciate answers that tackle this issue for general inla/inlabru.

Many thanks in advance,
Moritz





Finn Lindgren

unread,
Mar 12, 2025, 7:27:36 AM3/12/25
to Moritz Klaassen, R-inla discussion group
Hi,

how to handle spatio-temporally variable covariates depends on the
storage format, and will also be different for georeferenced data and
for point pattern models; the former just needs the covariate values
to be available for each observation row in the data set. For point
pattern models, bru() with model="cp" or lgcp() in inlabru, the
covariate needs to evaluable at every location of the likelihood
integration construction, which typically means providing it as a
terra object, with one layer per time point, so that inlabru can
evaluate the needed values internally, or alternatively explicitly
call eval_spatial() to generate the component input values:
Either
temperature(temperature_as_terra_object, main_selector = "month", ...)
or equivalently
temperature(eval_spatial(temperature_as_terra_object, .data.,
selector = "month"), ...)
This approach works both for georeferenced and for point pattern
models, if the covariate is available as a terra raster (also see
?eval_spatial or
https://inlabru-org.github.io/inlabru/reference/eval_spatial.html for
what other storage formats are supported).
Some more info is available in the help text for bru_component,
https://inlabru-org.github.io/inlabru/reference/bru_component.html

I don't know enough about the PointedSDMs internals to know whether
this also works in that wrapper package.

Finn
> --
> You received this message because you are subscribed to the Google Groups "R-inla discussion group" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to r-inla-discussion...@googlegroups.com.
> To view this discussion, visit https://groups.google.com/d/msgid/r-inla-discussion-group/f56dd526-b454-4f4b-9977-fabc6bbb3a7fn%40googlegroups.com.



--
Finn Lindgren
email: finn.l...@gmail.com
Reply all
Reply to author
Forward
0 new messages