The ascent package implements the
ASC-CFD (Assemblage Shift Characterization — Community
Functional Dynamics) framework.
Most functional diversity metrics quantify how much communities differ, but provide little information about how those differences are organized within functional space.
Communities may exhibit identical levels of functional turnover while following completely different ecological trajectories, including directional shifts, internal reorganization, or expansion and contraction of functional boundaries.
The ascent package implements the ASC-CFD framework to
explicitly decompose these processes.
ascent provides a multi-layer topological approach to
decompose functional community restructuring into positional,
dispersive, and boundary components, tested against sampling and trait
null models.
Whether you are evaluating temporal perturbations (e.g.,
deforestation, climate change) or spatial beta-diversity gradients,
ascent allows you to reconstruct the geometric trajectory
of ecosystems and identify the specific taxa driving these shifts.
The framework evaluates ecological dynamics by deconstructing them into three analytically distinct geometric layers within the retained functional space:
What does each layer measure?
ΔC → Where is the community moving? ΔFDis → How is biomass being redistributed? ΔFRic → Are functional boundaries expanding or collapsing?
Each layer is tested against two null models that ask different
questions: * A (sampling): individuals — or whole
samples, when both states have replicates — are reassigned at random
between the states. Is the change larger than expected from sampling
alone? * B stratified (traits): trait positions
are shuffled among the species of the contrast that have similar
abundances (groups of stratum_size, default 5). Does
the change depend on which traits the species have? For position,
the lower tail flags compensation (less change than expected from the
traits).
With functional entities (asc_entities()), A is also run
on abundances summed by entity, and asc_transitions()
splits the shift into a part between entities and a part within them:
this is the recommended way to detect replacement among functionally
similar species. For many communities (asc_pairwise()),
asc_null() runs a single global test per layer instead of
one p-value per pair.
Quick reading guide:
| A | B | Reading |
|---|---|---|
| no | — | no evidence of change beyond sampling |
| yes | upper tail | real change, directed by traits |
| yes | no | real change without detectable trait structure |
| yes | lower tail | less change than expected from traits (compensation; B has little power here: check entities) |
The asc_transitions() module projects species-specific abundance changes onto the observed ecosystem trajectory, identifying the taxa responsible for driving functional restructuring. This allows users to move beyond community-level metrics and directly quantify the contribution of individual species to directional ecosystem change.
Current frameworks quantify the magnitude of functional turnover between communities. ascent instead decomposes restructuring into three distinct mechanisms:
| Question | Classical beta diversity | ascent |
|---|---|---|
| How much changed? | ✓ | ✓ |
| In which direction did it change? | ✗ | ✓ |
| Did the centroid move? | ✗ | ✓ |
| Did internal functional dispersion change? | ✗ | ✓ |
| Did the functional boundaries expand or collapse? | ✗ | ✓ |
| Which species drove the shift? | ✗ | ✓ |
Install the released version from CRAN:
install.packages("ascent")Or the development version from GitHub:
# install.packages("devtools")
devtools::install_github("V3ndetta96/ascent")Here is a basic workflow evaluating the functional impact of deforestation on a bird community using mixed trait data (quantitative and binary).
library(ascent)
# 1. Define Traits and Abundances
# Note: Binary traits are set as factors to use the Gower metric.
traits <- data.frame(
Body_Mass = c(15, 20, 30, 45, 60, 90, 150, 250, 400, 600),
Frugivore = factor(c(0, 0, 1, 1, 1, 0, 1, 1, 1, 0))
)
rownames(traits) <- paste0("Sp", 1:10)
abund_time <- rbind(
Reference = c( 0, 0, 10, 15, 25, 20, 10, 8, 4, 2), # Old-growth forest
Impacted = c(40, 35, 15, 5, 0, 0, 0, 0, 0, 0) # Deforested
)
# 2. Execute the Paired Multi-Layer Framework
res <- asc_paired(
traits = traits, abund = abund_time,
sites = c("Site1", "Site1"), time = c("Reference", "Impacted"),
ref_time = "Reference", dist_method = "gower"
)
# 3. Evaluate the null models (A: sampling; B: traits)
res <- asc_null(res, n_perm = 999, seed = 123)
# 4. View Automated Ecological Diagnostic
summary(res)ascent includes built-in
ggplot2/patchwork methods to visualize the
PCoA trajectory, the 2D Convex Hull boundaries, and the Functional
Leverage (the specific taxa pulling or releasing the centroid).
plot(res, contrast = "Site1", type = "both", n_sp = 5)| Function | Purpose |
|---|---|
asc_baseline() |
Absolute baseline functional topology (CWM, FDis, FRic) for isolated communities |
asc_paired() |
Temporal or paired experimental contrasts |
asc_pairwise() |
Bidirectional spatial divergence across all community pairs |
asc_null() |
Null models A (sampling) and B stratified (traits); global test for
asc_pairwise(); optional entities |
asc_transitions() |
Species leverage, partition among shared/gained/lost species, split between/within entities |
asc_entities() |
Functional entities; k chosen by silhouette (Mojena and gap reported) |
assess_functional_space() |
Diagnostic tool to evaluate PCoA quality and dimensionality |
For a comprehensive guide, including spatial network analyses and detailed ecological interpretations, please read the official vignette:
vignette("ascent_tutorial")FRic is computed as the volume of the convex hull in the retained PCoA space. Key considerations:
NA.asc_null() evaluates each contrast (each site in
asc_paired()) separately. A needs counts of individuals
(whole numbers); with proportions only B is run. B shuffles traits only
among the species present in the contrast. B is slightly liberal for
dispersion (about 6.5 % false positives instead of 5 %) and when
individuals are captured in groups (about 7 %): treat p-values close to
0.05 with caution.
The Functional Leverage satisfies a strict mathematical decomposition:
\[\sum_{i=1}^{S} \text{Leverage}_i = \|\Delta C\|\]
where \(\|\Delta C\|\) is the absolute Euclidean distance between centroids. Each species’ leverage is the product of its demographic change (\(\Delta p_i\)) and its projection, measured from a reference point (by default the midpoint between the two centroids), onto the unit direction of the centroid shift:
\[\text{Leverage}_i = \Delta p_i \cdot \text{proj}(\mathbf{f}_i, \hat{v})\]
This property ensures that the sum of all individual species contributions exactly reconstructs the total centroid displacement. Species with positive leverage drive the shift; species with negative leverage resist it.
While the official manuscript is in preparation, if you use
ascent in your research, please cite the package
directly:
Muñoz-Li, R. R. & F. Alvarez-Denis (2026). ascent: Multi-Layer Decomposition of Functional Community Restructuring. R package. https://doi.org/10.5281/zenodo.20388185
The entry for the installed version is given by
citation("ascent").