I would like to calculate Shannon's diversity index for habitat diversity, i.e. the diversity of landscape factors. I have 11 locations (paired fields) for which I already defined (with QGIS) and calculated the proportions of 5 landscape factors (crops, grassland, semi-natural, forest and others) within a certain radius. I would like to compare the diversity of these five landscape factors among the 11 sites, but I have never done this before. I know how to use the R package "vegan" for calculating diversity indices with species, but not with landscape factors.

Could somebody please explain me how to deal with this?


Shannon's entropy does not assume species and is derived on any proportional measure. If you are familiar with deriving the index for with species, why would it be any different for proportion of landscape factors?

Let's take a look at the basic math behind the index and then write an R function that derives the index. You should be able to apply this logic to any matrix organized by row/column (as in a shapefile attribute table) or column/row for count or proportion values.

Starting with the basic equation: H' = -sum( Pi / ln(Pi) ) where P is the proportion of element i. We can break down the equation to procedural steps. First, we need to calculate the observation level proportions. From your description we can assume that your data is formatted as each landcover as a column and the row represent proportion (or count) for each observation.

Starting with counts, To derive the index we first need row sums and then need to divide all value by the row sums. With this matrix of proportions we can easily sum the raw proportions multiplied by the log of proportions.

Here is some dummy data we can work with.

spp <- read.csv("http://s3.amazonaws.com/RTools/spp.plots.csv")

First we calculate the row (or column) sums

total <- apply(spp, MARGIN = 1, sum)

Then we can use sweep to divide the matrix by the row sums

spp.prop <- sweep(spp, MARGIN = 1, total, "/")

Now we can write a simple function that will apply the Shannon's entropy equation to the data we have prepared and use apply to derive the index.

div <- function(x) { -1 * sum( x[x > 0] * log(x[x > 0]) ) } 
apply(spp.prop, MARGIN = 1, FUN = div ) 

If you already have your data as proportions then you can skip to the last step here. If we put this set of procedures into a function one can account for the data already being in proportions (or not) as well different input, where the observational level data may be organized in columns and not rows (the margin argument controls this and margin = 2 would change to columns).

shannon <- function(x, proportion = FALSE, margin = 1) {
  s <- function(x) { -1 * sum( x[x > 0] * log(x[x > 0]) ) }
  if( proportion == FALSE ) {
    spp.sum <- apply(x, MARGIN = margin, sum)
    spp.prop <- sweep(x, MARGIN = margin, spp.sum, "/")
    return( apply(spp.prop, MARGIN = margin, FUN = s ) )
  } else {
    return( apply(x, MARGIN = margin, FUN = s ) )

( H <- shannon(spp) )
( H <- shannon(spp.prop, proportion = TRUE) )

You can then convert the H' values to the effective number of species (ENS) to make the results a bit more interpretable. The ENS value represents the "real biodiversity" and allows you to compare the biodiversity with other communities. For example if you got a Shannon index of 1.907, this number can be converted into ENS of 7 which can be interpreted as the equivalent diversity of a community with 7 equally-common species. This is following the method proposed by Jost et al., (2006) and would apply to habitat diversity as well as species.

( ens <- round( exp ( H ), 0 ) ) 

As far as I can understand, you need to calculate Shannon diversity for some spatial data like Land Use or Land Cover. If so, you can use QGIS plugin LecoS or Grass module r.li, which were specially designed for computing diversity indexes for thematic raster data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.