New maintainer: Itai Granot. Author order is now Granot, Dubiner, Belmaker; Itai Granot and Shahar Dubiner contributed equally.
These change results relative to 1.0.0.
fit_isodars(dim = "ndim")) is
now a line (the first principal axis), not a hyperplane (the smallest
eigenvector) combined with “closest to equal allocation”. The old
approach biased niche breadth toward generalism.weights = "1/var") were
applied twice (effectively 1 / sd^4). They are now 1 / (sd^2 (1 +
slope^2)), applied once.isoderr(output = "SE") divided the bootstrap standard
deviation by sqrt(n_boot). The bootstrap SD is itself the
standard error, so “SD” and “SE” now both return it.fit_isodars() no longer recurses forever when an isodar
has a negative slope and a negative intercept.iai(abundances = NULL)) is now evaluated at the first
integer total with at least min_occupancy (default 1)
individual in every habitat. Previously the threshold was > 1e-9
individuals. If no total qualifies, one row of NA is
returned.hab_cols = NULL silently used every column of
data. Now hab_cols (or
n_habitats) is required.fit_isodars() accepts long-format data (one row per
species x site x habitat, columns named by species,
site, habitat, abundance and
optionally effort) and returns one fit per species
(isodar_fits). Counts are converted to densities per
reference_effort (default: the median effort). The
wide-format interface is unchanged.niche_breadth() returns, per species,
density-independent and density-dependent niche breadth with
site-bootstrap confidence intervals, the spillover abundance (the total
at which the least-favoured used habitat reaches one individual),
preference-reversal abundances, abandoned habitats and diagnostic flags
as columns. Printing it gives one summary line and the unit of
abundance. Density-dependent niche breadth is by default the limit at
infinite abundance (dependent_at = "asymptote"), computed
directly. The flags include a test of whether isodar intercepts differ
from sampling noise (multinomial null model, as in the paper). With
seed, each species gets its own random streams, and the
user’s random-number state is restored afterwards.summary() of a niche_breadth() result
counts the species with estimates and without warning flags, gives
quartiles of the estimates and, for each flag raised, how many species
raised it, what it means and what to do about it.iai_curve() and its plot() method give
niche breadth as a function of total abundance, with bootstrap bands,
each species’ density-independent value and asymptote, preference
reversals, and the totals at which two species’ curves cross. The curve
is drawn thinner beyond the largest observed site total, the x-axis
gives the unit of abundance, and the legend avoids the curves.
plot() of a niche_breadth() result plots its
curves.community_to_long() converts a community matrix
(samples x species) and a table of sample attributes into the long
format, pooling samples from the same site and habitat and summing their
effort.check_coverage() summarises sampling coverage per
species and habitat; group_sites() merges nearby sites
(complete linkage on great-circle distance, summing counts and efforts);
radius_sensitivity() shows how results change with the
grouping radius.fit_isodars() and niche_breadth() warn
when the data have an effort column that is not used, and
reference_effort without an effort column is
an error.simulate_isodars() simulates any number of habitats
(slopes, intercepts), optional missing
habitats (p_missing) and long-format output; the
three-habitat default gives the same numbers as before.moorea_fish: reef fishes of Moorea in
three habitats (the paper’s Table S2).vignette("isoniche") (get started),
vignette("data-preparation"),
vignette("diagnostics") and
vignette("method"); citation("isoniche"); a
pkgdown website.fit_isodars() (and isoderr()) gain
absent = "auto", which declares a habitat absent when the
species has no more than absent_max_count (default 0)
records in it across at least absent_min_sites (default 5)
sites where it was present in another habitat. Absent habitats are
excluded from the isodar fit, fixed at 0, and counted as 0 in the
inequality, so they lower niche breadth. Previously such habitats broke
the fit and iai() returned NA. Habitats with
no records but fewer informative sites give a warning and are kept. Use
absent = "none" for the old behaviour or name habitats
directly. A species that uses a single habitat has niche breadth 0.
isoderr() decides the absent set once, on the full data.
Results for species that use every habitat are unchanged.pairwise_niche() summarises pairwise isodars into
niche breadth indices (paper, revised Appendix S1). By default
(scale = "log") the indices do not depend on which habitat
of each pair is on the x-axis: slope deviations are
log(b)^2 and intercept deviations use the perpendicular
distance of the isodar from the origin,
abs(a) / sqrt(1 + b^2); it returns the inverse
root-mean-square deviations and the weighted means of
abs(log(b)) and of that distance, with optional weights
("1/var", the inverse perpendicular residual variance, or
numeric). Isodars with non-positive slopes are left out of the slope
indices with a warning. $cycles checks consistency: the
product of the slopes around each cycle of three habitats, which should
be 1, flagged beyond cycle_tolerance.
scale = "linear" gives the earlier indices (mean intercept
and slope, deviations (b - 1)^2 and a^2);
log_slope is a deprecated alias.fit_isodars(dim = "ndim", ndim_method = "latent")
estimates the line from incomplete sites (every site with at least two
habitats) as a one-factor model fitted with glmmTMB, and checks that the
habitats are connected through shared sites.
ndim_method = "auto" picks "pca" when all
sites are complete and "latent" otherwise.fit_isodars() returns classed tibbles
(isodars_pairwise, isodar_line).iai() allocates abundance among habitats by weighted
least squares on the pairwise isodar equations, constrained to the total
and to non-negative abundances, solved exactly by an active-set method.
(Setting negative habitats to 0 and re-solving, as first implemented,
could miss the optimum when a habitat dropped early should have been
kept. For the 325 species of moorea_fish, no
density-independent value or spillover abundance changes, and no value
in the paper’s reference table; density-dependent niche breadth rises
slightly for 3 species at the asymptote, by at most 0.014, and for 1
species at a total of 1000, by 0.002.) When the isodars do not determine
the allocation (for example, a habitat without records was kept),
iai() says so instead of failing with “singular
matrix”.isoderr(output = "CI") returns percentile bootstrap
intervals.iai() gives an informative error when
abundances contains NA, non-finite or negative
values.