--- title: "The method: isodar-adjusted niche breadth" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{The method: isodar-adjusted niche breadth} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4.5) ``` ```{r setup} library(isoniche) ``` This vignette explains what **isoniche** computes. The method is described in full by Granot, Dubiner & Belmaker (2026). ## Isodars Under density-dependent habitat selection, individuals settle where their expected fitness is highest. As a habitat fills up, its quality declines, so later individuals settle in the next-best habitat (the ideal free distribution; Fretwell & Lucas 1969). The densities in two habitats at which fitness is equal form a line, the *isodar* (Morris 1987): $$N_2 = a + b N_1 .$$ The intercept $a$ measures a density-independent preference: habitat 2 holds $a$ individuals before habitat 1 receives any. The slope $b$ measures how quickly habitat 2 fills compared with habitat 1 as total abundance rises. A species without habitat preference has $a = 0$ and $b = 1$. Isodars are estimated from replicates (sites, or surveys) in which the species' densities in each habitat are known. Because both densities are measured with error, they are fitted by total least squares (major-axis regression), not by ordinary regression. ## Why abundance-based indices are biased Whenever an intercept is not zero, the share of individuals in each habitat changes with total abundance. A rare species keeps most individuals in its preferred habitat and looks like a specialist; the same species, when abundant, spills into other habitats and looks like a generalist. A classic index, such as 1 - Gini of the habitat proportions, therefore partly measures abundance: ```{r bias, fig.height = 3.5} set.seed(2) sim <- simulate_isodars(slope1 = 1, slope2 = 1, int1 = 8, int2 = 8, noise = 1, n = 60) classic <- apply(as.matrix(sim[1:3]), 1, function(x) { x <- sort(x) n <- length(x) g <- 2 * sum(seq_len(n) * x) / (n * sum(x)) - (n + 1) / n (1 - g - 1 / n) * n / (n - 1) }) plot(sim$total_abundance, classic, log = "x", pch = 19, xlab = "Total abundance at the site", ylab = "Classic niche breadth (1 - Gini)") ``` All sites come from one species with fixed habitat preferences, yet niche breadth rises with abundance. Rarefaction (Cayuela et al. 2015) removes the effect of sample size on observed habitat use, but not this effect, which is part of how the species uses habitats. ## Pairwise isodars and the n-dimensional isodar With $H$ habitats there are $H(H-1)/2$ pairwise isodars, fitted separately, each with every site at which both habitats were sampled. The examples use three species of `moorea_fish`, reef fish counts from Moorea (BioTIME 2.0; Dornelas et al. 2025), as in the paper: ```{r pairwise} three <- c("Acanthurus nigrofuscus", "Scarus schlegeli", "Siganus argenteus") fish3 <- moorea_fish[moorea_fish$species %in% three, ] pw <- fit_isodars(fish3, species = "species", site = "site", habitat = "habitat", abundance = "abundance") pw$fit[[1]] ``` The n-dimensional isodar is a *line* through habitat space, not a plane. Equal fitness in $H$ habitats imposes $H - 1$ equalities, leaving one degree of freedom: as total abundance changes, densities in all habitats move together along one line. Its direction says how fast each habitat fills as abundance rises (the analogue of the slopes), and where it enters each habitat reflects density-independent preferences (the analogue of the intercepts). The line is the first principal axis of the site x habitat densities; `var_explained` is the share of variance it accounts for. ```{r line} ln <- fit_isodars(fish3, species = "species", site = "site", habitat = "habitat", abundance = "abundance", dim = "ndim") ln$fit[[3]] ``` When some sites lack some habitats, the line is estimated with a one-factor model that uses every site with at least two habitats (`ndim_method = "latent"`, fitted with **glmmTMB**). ## The isodar-adjusted inequality The *isodar-adjusted inequality* (IAI) allocates a chosen total abundance $T$ among habitats as the isodars predict, and computes 1 - Gini of that allocation, scaled to 0-1. For pairwise isodars the allocation solves the isodar equations $N_j - b N_i = a$ by weighted least squares subject to $\sum N = T$; habitats predicted negative are set to 0 and the rest re-solved. By default each isodar is weighted by its inverse variance, $1 / (sd^2 (1 + b^2))$ (`weights = "1/var"`). For the line, the allocation is the point where the line meets $\sum N = T$. Two values summarise the IAI: * **DI niche breadth**, at the *spillover abundance* $T_0$: the smallest total at which every used habitat holds at least one individual (per reference effort). It mainly reflects the intercepts. * **DD niche breadth**, as $T \to \infty$, where only the slopes (the direction of the line) matter. ```{r nb} nb <- niche_breadth(fish3, species = "species", site = "site", habitat = "habitat", abundance = "abundance", n_boot = 199, seed = 1) nb[c("species", "nb_di", "nb_di_lower", "nb_di_upper", "spillover_abundance", "nb_dd", "nb_dd_lower", "nb_dd_upper")] ``` Intervals come from resampling whole sites with replacement and refitting the isodars. The density-dependent value can also be computed at a given total (`dependent_at = 1000`, as in the paper) or at the largest observed site total (`dependent_at = "max_observed"`). ## The niche breadth curve Above $T_0$, until a habitat is clipped to zero, the allocation is linear in $T$. If, in addition, no two habitats swap rank anywhere above $T_0$, $$NB(T) = NB_{DD} + (NB_{DI} - NB_{DD}) \frac{T_0}{T},$$ so niche breadth is halfway between the two values at $T = 2T_0$. Where the predicted abundances of two habitats cross, the curve changes course (it keeps the form $A + B/T$, with new constants, between crossings); these *preference reversals* are reported, as are habitats used at low density and abandoned at high density: ```{r reversals} nb$abandoned nb$reversals[[1]] ``` ```{r curve, fig.height = 5} curve <- iai_curve(ln, n_boot = 99, seed = 1) plot(curve, abundances = 1000, crossings = TRUE) ``` Plotting against abundance relative to $T_0$ puts all DI values at 1: ```{r curve-relative, fig.height = 5} plot(curve, x_axis = "relative") ``` ## Indices from isodar parameters (Appendix S1) `pairwise_niche()` summarises the pairwise isodars directly. An isodar can be written with either habitat on the x-axis, so the indices are built to give the same answer either way: slopes enter as $(\log b)^2$, because $\log(1/b) = -\log b$, and intercepts as the perpendicular distance of the isodar from the origin, $d = |a| / \sqrt{1 + b^2}$. The indices are the inverse root-mean-square deviations from no preference, $1 / \sqrt{\sum w (\log b)^2 / \sum w}$ for slopes and $1 / \sqrt{\sum w d^2 / \sum w}$ for intercepts, and the weighted means of $|\log b|$ and $d$. The intercept index is in abundance units, so it depends on effort; the slope index does not. ```{r appendix} pn <- pairwise_niche(pw$fit[[1]], weights = "1/var") pn ``` The isodars of three habitats should agree with each other: going round the cycle A to B to C and back to A, the slopes multiply to 1. `$cycles` gives this product for every set of three habitats, and flags it when it departs from 1 by more than a factor of `exp(cycle_tolerance)` (default 1.5): ```{r cycles} pn$cycles ``` The earlier, orientation-dependent indices (mean intercept and slope, deviations $(b - 1)^2$ and $a^2$) are available with `scale = "linear"`. ## Simulating data `simulate_isodars()` generates densities in any number of habitats from known isodars, optionally with missing habitats, which is useful for checking the method on a known answer: ```{r simulate} set.seed(4) sim <- simulate_isodars(2, 2, 0, 0, noise = 0.5, n = 60) iai(fit_isodars(sim, hab_cols = c("hab1", "hab2", "hab3"), dim = "ndim"), abundances = 100) ``` The true value for these isodars is 0.571. ## References Cayuela, L., Gotelli, N. J. & Colwell, R. K. (2015). Ecological and biogeographic null hypotheses for comparing rarefaction curves. *Ecological Monographs*, 85, 437–455. Dornelas, M., Antão, L. H., Bates, A. E. et al. (2025). BioTIME 2.0: expanding and improving a database of biodiversity time series. *Global Ecology and Biogeography*, 34(5), e70003. https://doi.org/10.1111/geb.70003 Fretwell, S. D. & Lucas, H. L. (1969). On territorial behavior and other factors influencing habitat distribution in birds. I. Theoretical development. *Acta Biotheoretica*, 19, 16–36. Granot, I., Dubiner, S. & Belmaker, J. (2026). Why abundance-based indices of niche breadth are biased, and what can be done to improve them. *Ecology Letters* (in revision). Itai Granot and Shahar Dubiner contributed equally. Morris, D. W. (1987). Spatial scale and the cost of density-dependent habitat selection. *Evolutionary Ecology*, 1, 379–388.