Quick summary
Summarize this blog with AI
Calculate Shannon diversity from observed counts
For proportions p_i that sum to one, Shannon diversity is H = -sum(p_i * log(p_i)), as defined in the vegan reference. Natural logarithms give units of nats. A zero-count category contributes zero by the limiting convention 0 * log(0) = 0; computing that expression directly in R produces NaN, so omit zero probabilities from the sum.
This worked example uses fictional species counts and R 4.5.1. It calculates a descriptive plug-in estimate from one observed community. It does not estimate uncertainty, correct sampling bias or establish ecological causes.
Define the input policy
Use nonnegative counts or abundance weights measured on a common basis. In the function below, missing, infinite and negative inputs are rejected. An empty vector or an all-zero community returns NA_real_, because there is no observed total from which to define proportions. This policy distinguishes an empty sample from a sample containing exactly one species, whose diversity is zero. If positive weights span such an extreme range that a positive proportion rounds to zero, the function rejects the calculation explicitly instead of returning NaN.
shannon <- function(counts) {
if (!is.numeric(counts) || anyNA(counts) ||
any(!is.finite(counts)) || any(counts < 0)) {
stop("counts must be finite, nonnegative numeric values without NA")
}
total <- sum(counts)
if (!is.finite(total)) stop("total abundance is not finite")
if (total == 0) return(NA_real_)
p <- counts[counts > 0] / total
if (any(p == 0)) stop("positive proportions underflowed: input range is too large")
-sum(p * log(p))
}
counts <- c(oak = 10, pine = 20, birch = 30, maple = 40, elm = 0)
H <- shannon(counts)
print(round(H, 6)) # 1.279854
stopifnot(isTRUE(all.equal(H, 1.27985422583367)))
Verify zeros and simple reference cases
stopifnot(isTRUE(all.equal(shannon(c(10, 20, 30, 40, 0)),
shannon(c(10, 20, 30, 40)))))
stopifnot(shannon(c(8, 0, 0)) == 0)
stopifnot(isTRUE(all.equal(shannon(c(1, 1, 1, 1)), log(4))))
stopifnot(is.na(shannon(c(0, 0))), is.na(shannon(numeric(0))))
stopifnot(isTRUE(all.equal(shannon(counts * 5), H)))
bad <- tryCatch(shannon(c(1, NA)), error = function(e) e)
stopifnot(inherits(bad, "error"))
too_wide <- tryCatch(shannon(c(1e-300, 1e300)), error = function(e) e)
stopifnot(inherits(too_wide, "error"))
For four observed species, equal abundance gives the maximum log(4) = 1.386294. Multiplying every count by the same positive constant preserves proportions and therefore H. This is an algebraic property, not a promise that samples with different effort or detection rates can be compared without qualification.
Calculate one index per community
communities <- rbind(
woodland = c(10, 20, 30, 40, 0),
even = c(25, 25, 25, 25, 0),
one_species = c(100, 0, 0, 0, 0),
empty = c(0, 0, 0, 0, 0)
)
by_site <- apply(communities, 1, shannon)
print(round(by_site, 6))
# woodland 1.279854; even 1.386294; one_species 0; empty NA
stopifnot(isTRUE(all.equal(unname(by_site[1:3]), c(H, log(4), 0))))
stopifnot(is.na(by_site[4]))
Rows represent communities and columns represent the same species in each row. Keep missing counts distinct from observed zeros. Automatically deleting every row with a missing value changes which communities are analyzed; address the missingness before calculating or report those communities as incomplete.
Cross-check with vegan and interpret the scale
For this optional package comparison, install vegan first if needed. The example was tested with vegan 2.7-6. The comparison deliberately excludes the empty row, so the article's explicit all-zero policy remains in force.
from_vegan <- vegan::diversity(communities[1:3, ], index = "shannon")
stopifnot(isTRUE(all.equal(unname(from_vegan), unname(by_site[1:3]))))
effective_species <- exp(H)
print(round(effective_species, 6)) # 3.596115
stopifnot(effective_species > 1, effective_species < 4)
Exponentiating a natural-log Shannon value expresses it as the number of equally abundant species with the same index. Our fictional woodland has the same Shannon diversity as about 3.596 equally abundant species. This is an effective number, not a count of observed species. Compare like sampling protocols and taxonomic resolution, and report the logarithm base and zero/missing-value policies alongside the result.