Home > R > Computing the “Multivariate Environmental Similarity Surfaces” (MESS) index in R

Computing the “Multivariate Environmental Similarity Surfaces” (MESS) index in R

*edit oct 03 2012 *
The mess function is now part of the dismo package developped by Robert J. Hijmans, Steven Phillips, John Leathwick and Jane Elith (dismo 0.7-23)***

This post is about  the computation of the “Multivariate Environmental Similarity Surfaces” aka MESS in R. The MESS index was proposed by Elith et al (2010) [Methods in Ecology & Evolution 2010, 1, 330–342]. MESS can be computed with the Maxent software but I  wanted to perform all my data treatments within R/GRASS environment. For that reason I wrote a R function called mess.R.

Note that the function requires the R package raster developed by R. Hijmans and J. van Etten. Both the function and a tutorial can be downloaded for my site.

The present post provides some explanations, the mess.R function and some examples.

1- What is MESS?
MESS stands for Multivariate Environmental Similarity Surfaces. It is an index of similarity reporting the closeness of a point described by a set of environmental attributes to the distribution of these attributes within a population of reference points. The MESS approach has been proposed by Elith et al (2010). It works as BIOCLIM does but provides negative values which allows one to differentiate levels of dissimilarity. This is particularly valuable when considering points associated to values lying outside the range of the reference points.

2-The mess.R function

mess<-function(X,V,full=TRUE)
{
messi<-function(p,v){
    niinf<-length(which(v<=p))
    f    if(f==0) simi<-100*(p-min(v))/(max(v)-min(v))
    if(0    if(50<=f & f<100) simi<-2*(100-f)
    if(f==100) simi<-100*(max(v)-p)/(max(v)-min(v))
    return(simi)
    }
E<-extract(x=X,y=1:ncell(X))
r_mess<-X
for (i in 1:(dim(E)[2])) {
    e<-data.frame(E[,i]) ; v<-V[,i]
    r_mess[[i]][]<-apply(X=e, MARGIN=1, FUN=messi, v=v)
    }
rmess<-r_mess[[1]]
E<-extract(x=r_mess,y=1:ncell(r_mess[[1]]))
rmess[]<-apply(X=E, MARGIN=1, FUN=min)
if(full==TRUE) {
    out     layerNames(out)<-c(layerNames(X),"mess")
}
if(full==FALSE) out return(out)
}

The function mess.R allows the computation of the MESS index for a set of raster objets. raster objects are defined within the package raster developped by Hijmans & van Etten (2011). mess.R therefore requires that the package raster is properly installed and loaded using the command library(raster).

3-Examples
The following example uses the Bradypus data hosted in the package dismo (Hijmans et al., 2012). As with raster, dismo must be installed and loaded.

library(dismo);library(raster)
filename bradypus bradypus files ’/ex’, sep=’’), pattern=’grd’, full.names=TRUE )
predictors predictors<-dropLayer(x=predictors,i=9)
reference_points<-extract(predictors,bradypus)
mess.out<-mess(X=predictors,V=reference_points,full=TRUE)
plot(mess.out)

This is the result:


4-References
Elith J., Kearney M., & Phillips S. 2010. The art of modelling range-shifting species. Met. Ecol. Evol 1 :330-342.

Hijmans R.J. & van Etten J. (2011). raster : Geographic analysis and modeling with raster data. R package version 1.9-58. http://CRAN.R-project.org/package=raster

Hijmans R.J., Phillips S., Leathwick J. & Elith J. (2012). dismo : Species distribution modeling. R package version 0.7-17. http://CRAN.R-project.org/package=dismo


Advertisements
Categories: R Tags: ,
  1. pvanb
    13 October 2012 at 1402 46

    Thanks for sharing this, and great it is now part of the dismo package. I have been working on a similar function for GRASS. This was before I found your function, and now that I found your script, I am using it when working with smaller data sets.

    I am still running in problems when using much larger raster layers as input (e.g., across several countries in Africa). It works but I find in those cases that the raster package is not as fast as I would like (comparing with e.g., GRASS GIS). I am not sure this has something to do with my setup. Could you give tell how long it takes to run, e.g., with the examples given in your post?

    I am still trying to get my GRASS script to work too. Besides still being better in handling very large rasters, it is sometimes more convenient if I can run it directly in GRASS (no import / export of raster layers). It uses R as backend, but not for number crunching of the raster layers. In case you are interested, I’ll send you more info when I have ironed out some problems and when I have tested it properly.

    • 15 October 2012 at 1604 07

      Hi, I do agree with you, it might be somewhat time consuming for large rasters. We have the project to improve that point in the future. Actually, the Bradypus example took ca 20 seconds on my computer. I’m using R 2.15 in Linux Kubuntu Natty embedded within a Mac OS Lion 10.7.4 (thanks to parallel desktop). My computer is a Mac Book Pro with 2.2 GHz Intel Core i7 with 8 Go 1333 MHz DDR3 and Mac OS.

      I would be greatly interested by alternative tools under GRASS which is far more powerful that R when it comes to process large rasters. I am sure that your script would be very useful for many people ! Thanks.

      Jean-Pierre

  2. pvanb
    20 October 2012 at 2210 52

    Hi Jean-Pierre, it seems your code is a bit messed up by Word Press?

  3. pvanb
    20 October 2012 at 2311 28

    Hi Jean-Pierre, I have tried, but failed to find a way to run your code faster. However, thanks to some very smart people at Stack Overflow, I might have found a way after all. The key is using the ‘findInterval’ function. I wrote a quick post here http://pvanb.wordpress.com/2012/10/20/a-faster-way-to-calculate-mess-in-r-or-a-tribute-to-stack-overflow/ with some details. I haven’t tested it exhaustively, but it might give some ideas to speed up your code.

    • 21 October 2012 at 1503 32

      Hi ! this is simply great ! It should be included in future release of the package. 🙂

  4. pvanb
    21 October 2012 at 1503 43

    I have tested it a bit further, and it works for me, so yes, if included, it might improve the speed of the mess function (dramatically).

  5. 6 August 2013 at 808 23

    Wonderful article! That is the kind of information that are supposed to be shared around the net.

    Shame on the search engines for no longer positioning this put up higher!
    Come on over and talk over with my website . Thank you =)

  1. 20 October 2012 at 2311 19

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: