When all occs or bg coordinates fall outside the extent of envs (e.g., due to mistakenly passing coordinates in latitude-longitud order), ENMevaluate() raises an obscure error.
For example, this code uses climatic data from Patagonia and mistakenly inputs occs with lat-long (wrong order). The error is not useful:
library(terra)
library(ENMeval)
# 'example_data.csv' is attached in the issue
bad_occs <- read.csv("data/minimal_example.csv")
envs <- geodata::worldclim_global(var = "bio", res = 5, path = "data/worldclim")
## when cropped to Patagonia, swapped long-lat falls outside the map and produces an error
envs_cropped <- crop(envs, ext(-85, -35, -56, -35))
mod <- ENMevaluate(
occs = bad_occs,
envs = envs_cropped,
algorithm = 'maxnet',
tune.args = list(fc = c("L"), rm = 1),
partitions = "block")
Output:
*** Running initial checks... ***
* Randomly sampling 10000 background points ...
* Removed 18 occurrence localities that shared the same grid cell.
* Removed 1 occurrence points with NA predictor variable values.
* Clamping predictor variable rasters...
Error in `.rowNamesDF<-`(x, value = value) : invalid 'row.names' length
The problem starts when extracting values from envs at occs coordinates, lines 471-483
# remove cell duplicates
if(other.settings$removeduplicates == TRUE) {
occs.cellNo <- terra::extract(envs, occs, cells = TRUE, ID = FALSE)
occs.dups <- duplicated(occs.cellNo[,"cell"])
if(sum(occs.dups) > 0) if(quiet != TRUE)
message(paste0("* Removed ",
sum(occs.dups),
" occurrence localities that shared the same grid cell."))
occs <- occs[!occs.dups,]
if(!is.null(user.grp)) user.grp$occs.grp <- user.grp$occs.grp[!occs.dups]
occs.z <- occs.cellNo[!occs.dups,-which(names(occs.cellNo) == "cell")]
}else{
occs.z <- terra::extract(envs, occs, ID = FALSE)
}
# bind coordinates to predictor variable values for occs and bg
bg.z <- terra::extract(envs, bg, ID = FALSE)
In this case, swapped coordinates are so wrong that all predictors return NAs in occs.cellNo. Then, all but one row are considered duplicates and dropped. If removeduplicates == FALSE, it keeps all rows but they are just NAs. After that ENMevaluate() removes NAs. So it silently produces empty data frames for occs or bg, which later raises an error.
This can be avoided by checking that terra::extract doesn't get all NAs for occs and bg.
However, a bigger problem may be having no guard against lat-long instead of long-lat data. If the order is wrong but all the map is used, the model won't fail during checks.
I looked at how terra::vect handles this, and it uses a simple heuristic. Maybe many of these mistakes could be caught by checking that the name of the columns for occs and bg and throwing a warning.
I will open two small pull requests with those fixes in case you find them useful.
Thank you for your work!
Best,
Facundo
minimal_example.csv
When all
occsorbgcoordinates fall outside the extent ofenvs(e.g., due to mistakenly passing coordinates in latitude-longitud order),ENMevaluate()raises an obscure error.For example, this code uses climatic data from Patagonia and mistakenly inputs
occswith lat-long (wrong order). The error is not useful:Output:
The problem starts when extracting values from
envsatoccscoordinates, lines 471-483In this case, swapped coordinates are so wrong that all predictors return NAs in
occs.cellNo. Then, all but one row are considered duplicates and dropped. Ifremoveduplicates == FALSE, it keeps all rows but they are just NAs. After thatENMevaluate()removes NAs. So it silently produces empty data frames foroccsorbg, which later raises an error.This can be avoided by checking that
terra::extractdoesn't get all NAs foroccsandbg.However, a bigger problem may be having no guard against lat-long instead of long-lat data. If the order is wrong but all the map is used, the model won't fail during checks.
I looked at how
terra::vecthandles this, and it uses a simple heuristic. Maybe many of these mistakes could be caught by checking that the name of the columns foroccsandbgand throwing a warning.I will open two small pull requests with those fixes in case you find them useful.
Thank you for your work!
Best,
Facundo
minimal_example.csv