species accumulating in the neighbourhood
Spatial species accumulation curves built by fixed-focus expansion in C++.
Sample a focal point in continuous space, rank every sampling unit by its distance from that point, then count new species along the ranking. spacc repeats this from many focal points (Rcpp/RcppParallel backend), so the curve carries a confidence ribbon showing how richness depends on where expansion begins. The classical curve in vegan::specaccum() shuffles sites in random order, without using their spatial arrangement. spacc reproduces that random-order curve and adds the spatial one, so you can read the gap between them.
library(spacc)
coords <- data.frame(x = runif(100), y = runif(100))
species <- matrix(rbinom(100 * 50, 1, 0.3), nrow = 100)
# spatial accumulation around continuous focal points
sac <- spacc(species, coords, method = "knn", n_seeds = 100)
plot(sac)Spatial order, not random order
vegan::specaccum() accumulates sites in random or collector order, so geography drops out. spacc() keeps it: each curve expands around a continuous focal point, and the spread across focal points is the spatial signal. Run both and compare them directly.
sac <- spacc(species, coords, method = "knn", n_seeds = 100)
sac_random <- spacc(species, coords, method = "random", n_seeds = 100)
comp <- compare(sac, sac_random) # permutation, bootstrap, or AUC test
plot(comp)Seven expansion methods are available: knn (fixed-focus spatially constrained rarefaction), kncn (nearest-centroid expansion), nn_walk (a greedy nearest-neighbour traversal), gaussian and cone (distance- and direction-weighted growth), random (the classical null), and collector (data order). Geographic coordinates use distance = "haversine" with no projection step.
By default, continuous focal points are sampled uniformly from the convex hull of the eligible sites. Pass an sf polygon through focal_domain when the study boundary is known, or pass exact coordinates through focal_points for reproducible focal definitions.
Backend selection
The nn_walk and kncn methods pick a nearest-neighbour backend by site count, overridable with backend. Fixed-focus knn ranks distances directly.
| Backend | Distance | Cost per query | When |
|---|---|---|---|
| Exact (brute force) | any | O(n) | <= 500 sites (auto) |
| k-d tree (nanoflann) | Euclidean | O(log n) | > 500 sites (auto) |
| Ball tree | Haversine | O(log n) | > 500 sites, distance = "haversine"
|
Diversity beyond richness
Accumulation works for more than species counts. Each function carries the spatial ordering through to a different diversity measure, with map = TRUE and as_sf() for GIS output.
-
spaccHill(): Hill numbers (q = 0, 1, 2) along the accumulation, extending the iNEXT framework to spatial order. -
spaccBeta(): beta diversity with turnover and nestedness components (Baselga 2010). -
spaccCoverage(): coverage-based rarefaction via the Good-Turing estimator (Chao & Jost 2012). -
spaccPhylo()/spaccFunc(): phylogenetic (MPD, MNTD) and functional (FDis, FRic) accumulation. -
alphaDiversity()/gammaDiversity()/diversityPartition(): local, regional, and alpha-beta-gamma decomposition (Jost 2007).
Grouped and spatiotemporal accumulation
Split species into groups (native vs alien, families, any factor) and accumulate each under the same spatial site ordering, or add a temporal axis to weight space against time.
# same spatial ordering, separate curve per group
sac_grouped <- spacc(species, coords, groups = status, seed = 42)
plot(sac_grouped, facet = TRUE)
# sites sampled across years: weighted space-time distance
sac_st <- spacc(species, coords, method = "nn_walk",
time = site_years, w_space = 1, w_time = 0.5)Fitting and standardizing
-
extrapolate(): asymptotic richness models (Michaelis-Menten, Lomolino, Weibull, logistic, EVT). -
compare(): permutation, bootstrap, or AUC tests between curves. -
rarefy()/subsample(): rarefaction to common effort, spatial subsampling. -
coleman()/mao_tau()/spatialRarefaction(): analytical (non-simulation) curves. -
as_spacc(): bring an existingvegan::specaccum()object into the same plotting and comparison machinery.
Installation
install.packages("spacc") # CRAN
install.packages("pak") # development version
pak::pak("gcol33/spacc")Support
“Software is like sex: it’s better when it’s free.” — Linus Torvalds
I’m a PhD student who builds R packages in my free time because I believe good tools should be free and open. I started these projects for my own work and figured others might find them useful too.
If this package saved you some time, buying me a coffee is a nice way to say thanks. It helps with my coffee addiction.