Closed Labarcena-Jessica closed 7 months ago
Hi Jessica,
I agree that returning the grid cell id's would be useful, and maybe I'll add that in to the R package. In the meantime, it's pretty straightforward to do this. The reason that the coordinates were not matching cell centroids is because the points are randomly sampled in the tableFromEpmGrid
function, not selected from the set of possible cell centroids.
Here is how to get the cell ID's, depending on which type of grid cell you are working with:
library(epm)
library(sf)
library(terra)
# If working with hexagonal cells
tamiasEPM
tamiasEPM <- addPhylo(tamiasEPM, tamiasTree)
tamiasEPM <- addTraits(tamiasEPM, tamiasTraits)
morphoDisp <- gridMetrics(tamiasEPM, metric='disparity')
meanPat <- gridMetrics(tamiasEPM, metric='meanPatristic')
df_grid <- tamiasEPM[[1]]
xx <- tableFromEpmGrid(tamiasEPM, morphoDisp, meanPat, n = 100, minTaxCount = 2)
# convert the xy to spatial sf object
xxPts <- st_geometry(st_as_sf(xx, coords = c('x', 'y'), crs = st_crs(df_grid)))
# tests the intersection of each point with each grid cell.
# this returns a list, where each entry is the index of the grid cell that intersects with that point.
ptCheck <- st_intersects(xxPts, df_grid)
# add it back into the table.
xx$gridCell <- unlist(ptCheck)
head(xx)
# if working with square cells
tamiasEPM2 <- createEPMgrid(tamiasPolyList, resolution = 50000,
cellType = 'square', method = 'centroid')
tamiasEPM2 <- addPhylo(tamiasEPM2, tamiasTree)
tamiasEPM2 <- addTraits(tamiasEPM2, tamiasTraits)
morphoDisp <- gridMetrics(tamiasEPM2, metric='disparity')
meanPat <- gridMetrics(tamiasEPM2, metric='meanPatristic')
df_grid <- tamiasEPM2[[1]]
xx <- tableFromEpmGrid(tamiasEPM2, morphoDisp, meanPat, n = 100, minTaxCount = 2)
# easier with square grids and the terra package
xx$gridCell <- cellFromXY(df_grid, xx[, c('x', 'y')])
head(xx)
Thank you very much for your help, Pascal. That worked perfectly. I agree it will be helpful to include the grid ID in the output dataframe from tableFromEpmGrid.
On another note, while working with the function rasterToGrid() I found that it doesn't work with lapply. I have a list of 58 rasters and wanted to run the rasterToGrid, but it didn't work. I came up with a workaround by adapting the code of this function to work for a list of rasters.
df_values <- lapply(abundance_cropped, terra::extract, terra::vect(epm_obj[[1]]), list = FALSE)
newvals_abu <- lapply(df_values, function(x) aggregate(x , by = list(x$ID), FUN = mean))
abu_cell <- lapply(newvals_abu, function(x) sf::st_sf( vals = x[,3], geometry = sf::st_geometry(epm_obj[[1]])))
After this, I was able to run the tableFromEpmGrid function on the list of updated grids and emp object using lapply.
Is there any other way I can do this? Otherwise, it will be nice to update the rasterToGrid() function so it can work with a list of rasters.
This package is awesome for grid analysis.
Thank you for your help!
Jessica
Hi Jessica,
I've now pushed an update so that the github version of EPM can now return grid cell ID's for tableFromEpmGrid(). Can you test it out for me?
As for your question about rasterToGrid(), I also made a small update so that it can now properly handle multi layer spatRasters.
library(epm)
library(terra)
# generate a multi-layer SpatRaster
env <- rast(vect(tamiasEPM[[1]]), resolution = 100000, nlyrs = 5)
values(env[[1]]) <- sample(1:100, ncell(env), replace = TRUE)
values(env[[2]]) <- sample(1:100, ncell(env), replace = TRUE)
values(env[[3]]) <- sample(1:100, ncell(env), replace = TRUE)
values(env[[4]]) <- sample(1:100, ncell(env), replace = TRUE)
values(env[[5]]) <- sample(1:100, ncell(env), replace = TRUE)
env
# this now returns a list of items if the input was multi-layer.
newgrid <- rasterToGrid(env, target = tamiasEPM, fun = 'mean')
As for using lapply():
# convert the above multi-layer SpatRaster to a list of rasters
env2 <- lapply(1:nlyr(env), function(x) env[[x]])
newgrid2 <- lapply(env2, function(x) rasterToGrid(x, target = tamiasEPM, fun = 'mean'))
Does that make sense? Is this now doing what you were hoping?
Hi Pascal,
I suspect tableFromEpmGrid is not getting the gridCell ID properly. It produces a gridCellID column, but it has just the same numbers as the rowname, not the real gridID in the epm grid object. Also, for the function to work with the id = TRUE argument the epmObject needs to be the first argument in the function. If I run it with the epmObject as the second argument I get the following error. epm_test <- tableFromEpmGrid( t1, epm_ON_1km, id = TRUE) Error in (function (classes, fdef, mtable) : unable to find an inherited method for function ‘cellFromXY’ for signature ‘"integer", "data.frame"’
The rasterToGrid() function is working as expected when I use a SpatRaster object. I don't need to use lapply anymore as this solves the problem.
I am happy to run any other test.
Thank you!
Jessica
That was a good point about ordering of the inputs. That's fixed now. To me, it seems to be returning the proper id's. If you are still seeing this behavior (incorrect id), if you can create something reproducible for me to run, that would be very helpful.
Thanks for helping me troubleshoot this!
I am using an sf object. Could it be that? How can I better share the .RDS files for you to try?
If you could save the objects as .rds files and send them to me (pascal.title[at]stonybrook.edu), along with a short script that replicates the problem, then I can replicate what you are seeing.
This is now resolved. tableFromEpmGrid()
with id = TRUE
seems to return the correct grid cell indices.
Hello Pascal,
I was wondering if there is any way to get the gridID and add it to the df from the tableFromEpmGrid function. The problem is that I use the tableFromEpmGrid output to run GAM models, and now I want to update my grid cell by adding the predicted values from the model and mapping it. This is what I was trying to do, but I need help getting it to work.
get the grid object
df_grid <- epm_obj[[1]]
get the centroid values for each cell
templateCentroids <- sf::st_centroid(sf::st_geometry(df_grid$gridTemplate)) coord_grid <- sf::st_coordinates(templateCentroids )
What I noticed is that the values I get are not in correspondence with the X and Y on the tableFromEpmGrid output. I checked the projection and made sure all objects had the same one, but still nothing.
I would appreciate your input.
Thank you!
Jessica