PhilipMostert / PointedSDMs

Wrapper function for 'inlabru' for modeling species distribution models from disparate datasets.
23 stars 2 forks source link

Exporting predictions #6

Open RPJorge opened 1 year ago

RPJorge commented 1 year ago

Hello! I would like to ask about how to export models’ predictions. This package looks perfect for my research as I have different datasets of the same species with different bias. So far, I have achieved to develop the full integrated model I was looking for and check the relative importance of the datasets and differences using or not using them. I have also managed to create the prediction map. Everything looks great to me and I feel very optimistic about the results. However, I would like to export the predictions (for example as a raster) and be able to work with it in other environments (GIS for example) to carry out other analysis.

I haven’t found anything regarding this aspect, and functions like print.bruSDM_predict seem to have not been implement yet. The bruSDM_predict object I have obtained is something I am not used to work with and I haven’t found a solution for exporting it. Is there any way to export my predictions as a raster layer? Thank you in advance.

PhilipMostert commented 1 year ago

Hi RPJorge! Thank you for trying out the package, it's glad to hear everything is going well with it. The output of the predict function is a SpatialPixelsDataFrameObject (or at least a list of them), so it should be possible to save it as a raster file for further analysis in GIS. To do so you could use the terra R package like this to get a .tif file:

library(terra)
preds = predict(model, ...)
rasterPreds = terra::rast(preds[[1]])
terra::writeRaster(x = rasterPreds, filename = 'xx.tif')
ghost commented 11 months ago

Hi Philip! I am facing the same issue - I am unable to export the model predictions to a raster. Using predict creates a 'Large bruSDM_predict' object. When I use the code suggested above (terra::rast(preds[[1]])), I get the following error:

Error in h(simpleError(msg, call)) : error in evaluating the argument 'x' in selecting a method for function 'rast': unable to find an inherited method for function ‘ext’ for signature ‘"prediction"’

When I look at the bruSDM_predict object, I see an sf object with 4188 points. This number does not change based on my covariate raster resolution. Converting this sf object into a raster generates a blank raster. How do I get a raster output at the same resolution as my covariate rasters? Thank you.

PhilipMostert commented 11 months ago

Hi, maybe not the greatest solution, but you can do this:

class(preds[[1]]) <- c('sf', 'data.frame')
plot(terra::vect(spatial_predictions[[1]]), 'whichever_layer_you_want_to_plot')
ghost commented 11 months ago

Thank you! This still isn't letting me create a predicted raster of the appropriate resolution. I was wondering if it would be statistically ok to do this manually by extracting the coefficients from the model summary and applying them to the covariate raster layers.

PhilipMostert commented 11 months ago

Is there a particular error message that you're getting that prevents you from plotting the predictions? Don't think you can manually extract coefficients from the model summary since predictions from the model are made through samples generated from the posterior.

ghost commented 11 months ago

If it creates a sf object within the bruSDM_predict, I can plot it using the plot function, but I cannot extract a raster from it. If I use format='terra' in the predict function, it is giving me the following error:

Warning in fm_onto_mesh(mesh, loc, crs = crs) : Unclear if the 'loc' class ('simpleError', 'error', 'condition') is of a type we know how to handle. Error in matrix(is.na(as.vector(loc)), nrow = nrow(loc), ncol = ncol(loc)) : non-numeric matrix extent In addition: Warning message: [setValues] values is larger than the size of cells

I need to extract a raster with the same resolution as the input covariate rasters. Would it be possible to do that? Thank you!

ghost commented 11 months ago

Additional info: Using format='sp' or the default (sf) creates a bruSDM_predict object with a nested sp or sf object, but this is of limited resolution and results in a blank raster if coerced into a raster. Using format='terra' results in an error. The actual error message changes a bit depending on the settings used in the predict() call, but the common part is as follows:

Error in (function (classes, fdef, mtable) : unable to find an inherited method for function ‘vect’ for signature ‘"SpatRaster"’ In addition: Warning message: [setValues] values is larger than the size of cells

PhilipMostert commented 11 months ago

It's not really my expertise, but the only solution I can find that might work is:

class(preds[[1]]) <- c('sf', 'data.frame')
vectLyr <- terra::vect(preds[[1]])
rastLyr <- terra::rast(preds[[1]])

lyr <- terra::rasterize(vectLyr, rastLyr, field = 'mean')
terra::writeRaster(lyr, 'xx.tif')
VirginiaMorera commented 10 months ago

Long shot but have you tried naming the column you want to turn into a raster, instead of using the index?

My code is from before the last big update so it might not be the same, but I did

raster(RD_pred$predictions['mean'])

this is with the old raster package but should work with the terra too, but I remember having to name the layer specifically by its column name in the spatialPixel df since the indexing wouldn't work.

Sorry I can't be more specific but this was a while ago, but worth a try!

ghost commented 10 months ago

Thank you for your suggestions! Unfortunately this doesn't work either.