Thursday, June 24, 2021

Problems with background test in ENMTools R package

At some point, I think fairly recently, something got messed up in the background tests of the ENMTools R package and it is building the models for the permutation tests using incorrect presence points.  I think I've found the issue and am working on a fix right now, but if you're using a recent version from CRAN or GitHub to do background tests I would not trust those results until a fix gets released.  I will do my damnedest to get that done this afternoon, Japan time.  Really sorry for any inconvenience this might have caused.

edit: This issue has now been fixed and the fixed version is live on CRAN.  If you've got any studies underway using the background test (similarity test), please reinstall ENMTools and run them again.

Sunday, May 16, 2021

Removing points from suitability plots

This is a question I got via email: how do you remove occurrence points from the suitability plots that are spit out by ENMTools modeling functions?

Luckily this is quite easy, as these are just ggplot objects.


library(ggedit) <- enmtools.maxent(iberolacerta.clade$species$monticola,

                           euro.worldclim, test.prop = 0.3)

with.points <- plot(


without.points <- remove_geom(with.points, "point", 1:2)


For some reason ggedit's remove_geom function gets mad when you pass it two layer numbers (1:2), but it still works.  It doesn't work if you only pass it one number.  Go figure.

Thursday, May 6, 2021

Fixing bugs, adding the ability to use bias layers

 Version 1.0.4 of ENMTools is now on GitHub.  It fixes some issues with the permutation tests for model fit, and just a few other minor usability fixes.  It also adds two important things:

A check.env() function that will sort through your environmental raster stack and check to see that all layers have NAs in the same grid cells.  This has been causing issues for some people because the background selection for various tests and model functions treats the top layer of the environmental raster stack as a mask.  If some of the other layers had NA values in grid cells where the first one didn't, this could cause the package to draw some NAs for data points.  Running your layers through check.env() before using them to construct range rasters or run models/tests is advisable, but you should only have to do it once.  Basically the syntax is:

env <- check.env(env)

Where "env" is your raster stack.  It may take a few minutes if your rasters are huge.

The other big change is the addition of bias layers to all modeling functions.  If you have a raster representing sampling bias, you can now pass it into any modeling function and the background points will be drawn in proportion to the value in each grid cell.  For instance:

my.glm <- enmtools.glm(my.species, env, bias = biaslayer)

As always, if you want to use the GitHub version you just run


Monday, April 5, 2021

Estimating bias in transferring species distribution models

As some of you may have seen, I had a recent paper come out with Alex Dornburg, Teresa Iglesias, and Katerina Zapfe on the effects of climate change on Australia's only endemic Pok√©mon, kangaskhan.

While the paper is obviously intended to be humorous (seriously, check out Supplement S1 because it is ridiculous), there's actually a pretty cool new method involved here.  We show that a given study design (i.e., sample size, study area, choice of predictor variables, modeling algorithm, and climate scenario) can create massive biases in the sorts of predictions you might make when building and transferring models.  In some cases these can be so strong that the qualitative prediction you make (e.g., range contraction or expansion) is completely unaffected by the data; the data can only affect the magnitude of the predicted change, not the direction of it.

The super cool bit (in my opinion) is that we show that you can make a fairly simple modification to the Raes and ter Steege (2007) test that allows you to estimate how biased a given design is.  This gives you some idea of which general methodological approaches let the data have the most affect on the outcome, and we even show how you can do this in a spatial context to tell you WHERE your model is more driven by bias and where it's more driven by data.  We think this is a super useful new tool that may give stakeholders some quite valuable information when it comes to applying models to make decisions.

I'll set up a video tutorial on how to do this soon, and eventually we'll probably come up with some sort of wrapper function in ENMTools that simplifies the process.  Right now, though, there are worked examples in the Dryad repo for the supplementary code.  That's here:

Warren, Dan; Dornburg, Alex; Zapfe, Katerina; Iglesias, Teresa (2021), Data and code for analysis of effects of climate change on kangaskhan and summary of simulations from Warren et al. 2020, Dryad, Dataset,

The "block" crossvalidation feature is currently broken on CRAN

 As part of fixing the recent spatstat-related issues, I somehow managed to roll back some much older changes and as a result broke the block crossvalidation features on the CRAN version of ENMTools.  I'm working on an update now that will fix it, but in the interim if you need that feature please just use the "develop" branch from GitHub.  As before, the code for that is:


devtools::install_github("danlwarren/ENMTools", ref = "develop")

Sunday, April 4, 2021

ENMTools is back on CRAN, minus ppmlasso models

 We've finished the changes necessary to come up to date with the changes to the spatstat package, and ENMTools is now back on CRAN.  Unfortunately one of the changes we had to make was to disable ppmlasso models, since they're not yet compatible with the new spatstat.  We don't know how long those are going to be unavailable, but it could be a while.

Thursday, April 1, 2021

Specifying regularization multiplier for maxent from ENMTools

 I just got a question about this and I figured I should post about it, since it's quite counterintuitive.  If you need to specify a regularization multiplier in ENMTools for Maxent to use, you need to do it with the "-b" flag and the numerical argument passed as two separate arguments.  For instance if you wanted to model Iberolacreta monticola from the sample data using a regularization multiplier of 5, you'd do this:


mont <- iberolacerta.clade$species$monticola <- enmtools.maxent(mont, euro.worldclim, args = c("-b", "5"))

Tuesday, March 30, 2021

ENMTools currently unavailable on CRAN

Due to some changes to the spatstat package, quite a few packages were kicked off CRAN today including ENMTools.  We have submitted a version that (we think) fixes these issues, but it's currently still in review.  Until it's back up, you can always install the development version from github:


devtools::install_github("danlwarren/ENMTools", ref = "develop")

Sunday, March 21, 2021

CRAN version of ENMTools is currently not working for some people

Due to updates with the spatstat package, the CRAN version of ENMTools is currently not working for some people.  We've got a develop version on github that seems to be doing okay, though, so you can install that by typing:


devtools::install_github("danlwarren/ENMTools", ref = "develop")

We should have the CRAN version working soon.  Sorry for the inconvenience; apparently all of the authors of packages depending on spatstat were supposed to receive emails months ago saying that all of this was coming down the pipe, but none of us seem to have gotten one.

Wednesday, March 10, 2021

Doing replicates of ENMTools models

This is coming from a question on the maxent google group.  Someone wanted to know how to do multiple replicates of an ENMTools model.  At some point we need to create some code for that, but for now it's not too hard to do it using R's existing "replicate" function.

# First we'll load in ENMTools


# Now we're just grabbing a species object out of the built-in data 

mont <- iberolacerta.clade$species$monticola

# Here we're using the "replicate" function to repeat the modeling command 10 times 

# and stuff the results into a list

my.models <- replicate(10, 

          enmtools.gam(mont, euro.worldclim[[c(1,12)]], test.prop = 0.3), 


# And now we want to give each rep a name

names(my.models) <- paste0("rep", 1:10)

# This is a slightly tricky bit - basically I'm grabbing the suitability raster out of each

# replicate model, and then turning them into a raster stack

rep.rasters <- stack(sapply(my.models, function(x) x$suitability))

# Now that we've got that, we can calculate any summary stats we want on that stack

# Here's how you'd plot the mean suitability

mean.raster <- calc(rep.rasters, fun = mean)


# Here's how you'd do variance

var.raster <- calc(rep.rasters, fun = var)


# And here's minimum suitability

min.raster <- calc(rep.rasters, fun = min)


Tuesday, January 19, 2021

Application note for ENMTools R package is out today!

 Hooray, it's finally out!

This is the culmination of a lot of work by a lot of people, and I just wanted to take this opportunity to express my gratitude towards my coauthors, collaborators, and co-conspirators.  

Tomorrow we start working on version 2.0...