Compute focal means of the indicators of each vegetation type. At each cell, these give the proportions of the types. Multiply each by its negative logarithm and sum: that's the diversity index.
You will find that even for large numbers of categories (even into the hundreds), this is fantastically faster than the brute-force method of tabulating each neighborhood in turn, even with tiny neighborhoods. That is because it is carried out by means of convolutions, achieving O(m*n*log(m*n)) scaling for m rows and n columns, regardless of the neighborhood size. The brute-force tabulation method simply will not complete executing in any reasonable time on any rasters of meaningful size or using large neighborhoods.
The code at the end illustrates the procedure. It uses a 41 by 41 circular neighborhood on a 500 by 800 raster involving five categories; the timing is under 10 seconds. That's poor, actually: it can be improved by several of orders of magnitude on other platforms. However, it might be good enough for production work when rasters are not too large.
This code gives results that differ from vegan
and from another answer in this thread. The reason is subtle: focal
first multiplies all elements in the neighborhood by the focal weights and then passes all values to its function. For non-rectangular neighborhoods that introduces some zeros. Those zeros are not included in the neighborhood and therefore should not be tabulated. However, the approach using table
actually does tabulate the frequencies of those zeros. The effect is to add a constant value (equal to -r *log(r) where r is the proportion of zeros in a neighborhood) except around the edges (where the neighborhood shape, and therefore r, can change).
library(raster)
m <- 500 # Rows
n <- 800 # Columns
cellsize <- 250 # Meters
p <- (1:5)^2 # Relative probabilities of vegetation; first is NoData
radius <- 5000 # Meters
#
# Create sample data.
#
set.seed(17)
x <- matrix(sample.int(length(p), m*n, replace=TRUE, prob=p), nrow=m)
#
# Convert to raster.
#
x.r <- raster(x, xmn=0, ymn=0, xmx=n*cellsize, ymx=m*cellsize)
#
# Diversity index.
#
diversity <- function(x.r, radius, type="circle", verbose=TRUE) {
#
# Create focal weights matrix.
#
nbrhd <- focalWeight(x.r, radius, type=type)
#
# Compute focal means of indicators.
#
entropy.r <- calc(x.r, function(x) 0)
x.log <- function(x) ifelse(x==0, 0, x*log(x))
for (i in 1:length(p)) {
if (verbose) cat("Computing indicator for category", i, "... ")
z <- system.time({
entropy.r <- entropy.r - calc(focal(x.r == i, nbrhd), x.log)
})
if (verbose) cat(z[3], "seconds.\n")
}
return (entropy.r)
}
#
# Plot the original and its entropy.
#
entropy.r <- diversity(x.r, radius)
par(mfrow=c(1,2))
plot(x.r, main="Original")
plot(entropy.r, main="Entropy")