Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1D spde for flexible covariates in PointedSDMs #21

Closed
klaassenmo opened this issue Feb 28, 2025 · 2 comments
Closed

1D spde for flexible covariates in PointedSDMs #21

klaassenmo opened this issue Feb 28, 2025 · 2 comments

Comments

@klaassenmo
Copy link

Dear Philip,

I am working on data integration for SDMs where i want to model my PO data using a dynamic variable (temperature) and my PA data using static variables (bathymetry and slope).

Our current integrated model looks like this:

Integrated Model: PO (Temperature) + PA (Bathymetry & Slope)

organizedData <- startISDM(
data = list(po_sf, pa_sf), # Combine PO and PA data
Mesh = mesh,
Projection = proj_azores,
spatialCovariates = env_stack_bs_masked, # Bathymetry and slope for PA
pointCovariates = list("temperature", NULL), # Temperature for PO, no additional covariates for PA
Boundary = study_area_sf,
responseCounts = "counts", # Response for PO data
responsePA = "presence_absence", # Response for PA data
pointsSpatial = "copy", # Share spatial random field
Formulas = list(
covariateFormula = ~ bathymetry + slope, # Covariates for PA
pointCovariateFormula = ~ temperature Covariates for PO
)
)

modelRun_Int <- fitISDM(organizedData, options = list(
control.inla = list(strategy = "simplified.laplace", int.strategy = "eb"),
control.compute = list(return.marginals.predictor = TRUE)
))

summary(modelRun_Int)

and it works fine - also the dynamic predictions. As you see I pass the static variables as spatialCovariates and the temperature as pointCovariate for the PO data, since I have temperature values for multiple months and want to fit a "global" model that i can predict onto different months.

Now, need to extend this functionality to model the covariate effects flexibly. The motivation behind this is that I'm working with virtual species whose habitat suitability functions from the covariates are either Gaussian or logistic. To capture these non-linear relationships, I would like to build 1D SPDE models for the covariates. While I found some resources of people implementing this directly in inla, I would still like to stick with the PointedSDMs package since I really like working in this package.

My question to you is:

  • I am a bit lost where 'functionality for integrating flexible covariate models might be implemented in PointedSDMs. I assumed via specifyISDM using an updateFormula parameter. However, the exact location and process for incorporating the 1D SPDE models is unclear to me. If I do work with flexible covariates, can I still define my model as above or do I have to pass all covariates as pointcovariates? My very initial trials doing this with :

organizedData$updateFormula(
datasetName = 'po_sf', # PO dataset
newFormula = ~ f(temperature, model = spde_temp$spde) # 1D SPDE for temperature
)

(for all the covariates) always gave me the following error:
Error in isDiagonal(from) : unexpected type "list" in 'typeToKind'

I really appreciate your help with this - I am very new to this Package and modelling in INLA in general, so many thanks in advance!

Moritz

@PhilipMostert
Copy link
Owner

Hi!

Great to see you're using the package. The .$updateFormula function is only really used to change the covariates of the formula, and doesn't really deal with any other types of effects. Think if you wanted to include the spde1 for the temperature covariate you would need to use the .$changeComponents function. So do .$changeComponents('temperature(main = temperature, model = INLA::inla.matern.2d(fmesher::fm_mesh_1d(*arguments_here*))') and then I think that should work. I don't think it would work if you saved the mesh as its own object. Then you can use the .$updateFormula function if you would like to. Please let me know if this would work with your example.

@klaassenmo
Copy link
Author

Hi Philip.

Many thanks for your response - greatly appreciated! – that indeed helped me get a 1D SPDE model working for temperature. However, I got stuck trying to do the same for bathymetry and slope, which still appear as linear (fixed) effects in the model summary. However, I want to allow all my covariates to be flexible. Below is a quick recap of what I tried:

1. Start iSDM
organizedData <- startISDM(
data = list(po_sf, pa_sf),
Mesh = mesh, # 2D mesh for the spatial field
Projection = proj_azores,
spatialCovariates = env_stack_bs_masked, # for bathymetry, slope
pointCovariates = list("temperature", NULL), # dynamic var for PO
Boundary = study_area_sf,
responseCounts = "counts", # name of the presence-only response
responsePA = "presence_absence", # name of the PA response
pointsSpatial = "copy",
Formulas = list(
covariateFormula = ~ bathymetry + slope,
pointCovariateFormula = ~ temperature
)
)
2. Change components
temperature
organizedData$changeComponents(
"temperature(
main = temperature,
model = INLA::inla.spde2.pcmatern(
mesh = fmesher::fm_mesh_1d(
loc = seq(-3, 3, length.out = 20),
boundary = 'free'
),
alpha = 2,
prior.range = c(1, 0.05),
prior.sigma = c(1, 0.05),
constr = TRUE
)
)"
)

bathymetry
organizedData$changeComponents(
"bathymetry(
main = bathymetry,
model = INLA::inla.spde2.pcmatern(
mesh = fmesher::fm_mesh_1d(
loc = seq(-3, 3, length.out = 20),
boundary = 'free'
),
alpha = 2,
prior.range = c(1, 0.05),
prior.sigma = c(1, 0.05),
constr = TRUE
)
)"
)

slope
organizedData$changeComponents(
"slope(
main = slope,
model = INLA::inla.spde2.pcmatern(
mesh = fmesher::fm_mesh_1d(
loc = seq(-3, 3, length.out = 20),
boundary = 'free'
),
alpha = 2,
prior.range = c(1, 0.05),
prior.sigma = c(1, 0.05),
constr = TRUE
)
)"
)

3. Update formula

organizedData$updateFormula(
datasetName = "po_sf",
newFormula = ~ temperature
)

organizedData$updateFormula(
datasetName = "pa_sf",
newFormula = ~ bathymetry + slope
)

4. Fit model
modelRun_Int <- fitISDM(
organizedData,
options = list(
control.inla = list(strategy = "simplified.laplace", int.strategy = "eb"),
control.compute = list(return.marginals.predictor = TRUE)
)
)

5. Summary
Then, when i call modelRun_Int$summary.random, the 1d spde for bathymetry and slope did not seem to have worked..

$Fixed__Effects__Comps
ID mean sd 0.025quant 0.5quant 0.975quant mode kld
1 bathymetry -0.1219621 0.19559199 -0.5053154 -0.1219621 0.2613912 -0.1219621 0
2 slope 0.3875298 0.03878048 0.3115214 0.3875298 0.4635381 0.3875298 0

$temperature
ID mean sd 0.025quant 0.5quant 0.975quant mode kld
1 0 -1.51031520 2.0046330 -5.43932371 -1.51031520 2.41869330 -1.51031520 0
2 1 -1.21456540 1.3455257 -3.85174726 -1.21456540 1.42261647 -1.21456540 0
3 2 -1.02996879 0.8615663 -2.71860771 -1.02996879 0.65867013 -1.02996879 0
4 3 -0.93171622 0.5128347 -1.93685382 -0.93171622 0.07342137 -0.93171622 0
5 4 -0.90266704 0.2887727 -1.46865117 -0.90266704 -0.33668291 -0.90266704 0
6 5 -0.93094690 0.2262311 -1.37435173 -0.93094690 -0.48754208 -0.93094690 0
7 6 -1.00791518 0.2694184 -1.53596558 -1.00791518 -0.47986478 -1.00791518 0
8 7 -1.03071769 0.2798673 -1.57924746 -1.03071769 -0.48218792 -1.03071769 0
9 8 -0.81756404 0.2800840 -1.36651854 -0.81756404 -0.26860953 -0.81756404 0
10 9 -0.44792036 0.2754969 -0.98788437 -0.44792036 0.09204365 -0.44792036 0
11 10 -0.03915201 0.2866139 -0.60090493 -0.03915201 0.52260092 -0.03915201 0
12 11 0.48650152 0.2815638 -0.06535338 0.48650152 1.03835643 0.48650152 0
13 12 0.84174522 0.2694761 0.31358180 0.84174522 1.36990865 0.84174522 0
14 13 0.91332267 0.2819402 0.36073012 0.91332267 1.46591522 0.91332267 0
15 14 0.98128634 0.2716440 0.44887389 0.98128634 1.51369879 0.98128634 0
16 15 0.98003648 0.2682899 0.45419785 0.98003648 1.50587511 0.98003648 0
17 16 1.09091707 0.3142412 0.47501556 1.09091707 1.70681858 1.09091707 0
18 17 1.27121453 0.5306794 0.23110206 1.27121453 2.31132700 1.27121453 0
19 18 1.55411121 0.9030577 -0.21584928 1.55411121 3.32407170 1.55411121 0
20 19 1.97831264 1.4298773 -0.82419542 1.97831264 4.78082070 1.97831264 0

Many thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants