EcoNiche is an R package for estimating taxon-level and community-level niche position and niche breadth under continuous, multidimensional environmental gradients.
EcoNiche is designed for ecological community data in which environmental gradients are continuous, multivariate and potentially confounded by background variables. The package combines constrained ordination, partial constrained ordination, generalized additive models and classical discrete-state niche breadth indices in a reproducible R workflow.
The core idea is to estimate niche position and conditional niche breadth in a continuous environmental space, rather than relying only on arbitrary discrete sample states.
Package version: 1.0.3
EcoNiche can be installed from CRAN:
install.packages("EcoNiche")
The stable release is distributed through CRAN. The GitHub repository provides the development version, source code and issue tracking.
The development version can be installed from GitHub:
# install.packages("remotes")
remotes::install_github("zhoushuotao/EcoNiche")
Source code and issue tracking are maintained on GitHub:
EcoNiche provides three complementary analytical modules.
This is the primary EcoNiche workflow. It uses canonical correspondence analysis (CCA) and partial CCA to:
Use this workflow when the ecological question involves continuous multivariate gradients and covariate control.
The GAM module fits taxon-specific nonlinear response curves along one selected environmental gradient. It returns response optima and breadth50, the interval over which the fitted response remains at or above 50% of the fitted peak.
GAM results are useful for visualizing nonlinear responses and comparing curve-derived response ranges. However, breadth50 describes a response along one selected gradient and should not be treated as a direct substitute for ordination-based niche breadth in multivariate environmental space.
EcoNiche also calculates classical Levins and Shannon niche breadth metrics. These treat samples, or bins along a gradient, as discrete states.
These metrics are provided mainly as benchmarks for comparison with the continuous-gradient ordination workflow. Gradient-binned Levins' breadth remains sensitive to bin number, binning strategy and the distribution of samples along the gradient.
Analytical structure of EcoNiche. CCA and partial CCA define a composite environmental gradient for estimating niche position and conditional niche breadth. GAM provides single-gradient response curves, and Levins' index serves as a discrete-state benchmark.
EcoNiche v1.0.3 includes a plant community dataset for reproducible examples:
plant_otu: species-by-sample abundance matrix, with taxa in rows and samples in columns.plant_env: sample-by-environment data frame, with samples in rows and environmental variables in columns.plant_group: named vector defining the group of each sample.library(EcoNiche)
data("plant_otu")
data("plant_env")
data("plant_group")
identical(colnames(plant_otu), rownames(plant_env))
identical(names(plant_group), colnames(plant_otu))
dim(plant_otu)
dim(plant_env)
length(plant_group)
Most EcoNiche functions assume the same data orientation:
otu: taxa in rows, samples in columns.env: samples in rows, environmental variables in columns.group: named vector or factor; names must be sample IDs.The example below uses precipitation, soil moisture, available phosphorus and soil pH to construct the focal multivariate environmental gradient. Annual mean temperature is used as a covariate and as the plotting gradient.
library(EcoNiche)
data("plant_otu")
data("plant_env")
data("plant_group")
res_grad <- cca_workflow_gradient(
otu = plant_otu,
env = plant_env,
sel = c("AMP", "Moisture", "AP", "pH"),
covariates = "AMT",
var = "AMT",
method = "loess",
galaxy_colnum = FALSE
)
head(res_grad$step3$species)
res_grad$step3$plot
res_grad$step4$plot
For group-level or sample-level aggregation:
res_group <- cca_workflow_group(
otu = plant_otu,
env = plant_env,
group = plant_group,
sel = c("AMP", "Moisture", "AP", "pH"),
covariates = "AMT",
var = "AMT",
choice = "all",
method = "loess",
plot_type = "sample",
galaxy_colnum = FALSE
)
head(res_group$step5$sample_summary)
head(res_group$step5$group_summary)
res_group$step6$plot
The wrapper functions are convenient for routine use. For a step-by-step implementation using the six core functions, see the package vignette and the supplementary example code associated with the EcoNiche manuscript.
The wrapper workflow above is composed of six exported functions:
cca_prep_env(): prepare selected environmental variables and covariates.cca_fit_ordination(): fit CCA and partial CCA ordination models.cca_calc_species(): calculate taxon-level niche position and niche breadth.cca_calc_gradient(): map site-level niche position to an environmental gradient.cca_calc_group(): aggregate breadth estimates to sample and group levels.cca_plot_group_env(): visualize aggregated breadth along an environmental gradient.Example skeleton:
step1 <- cca_prep_env(
env = plant_env,
sel = c("AMP", "Moisture", "AP", "pH"),
constrain = "AMT",
galaxy_colnum = FALSE
)
step2 <- cca_fit_ordination(
otu = plant_otu,
env = plant_env,
sel = c("AMP", "Moisture", "AP", "pH"),
covariates = "AMT",
galaxy_colnum = FALSE
)
step3 <- cca_calc_species(
otu = plant_otu,
site_width = step2$site_width,
site_pos = step2$site_pos,
method = "loess",
make_plot = TRUE,
top_node = 10000
)
step4 <- cca_calc_gradient(
env = plant_env,
site_pos = step2$site_pos,
var = "AMT",
make_plot = TRUE,
galaxy_colnum = FALSE
)
step5 <- cca_calc_group(
otu = plant_otu,
site_width = step2$site_width,
group = plant_group,
choice = "all"
)
step6 <- cca_plot_group_env(
env = plant_env,
sample_summary = step5$sample_summary,
var = "AMT",
group = plant_group,
plot_type = "sample",
method = "loess",
make_plot = TRUE,
galaxy_colnum = FALSE
)
sel and covariates
EcoNiche separates environmental predictors into:
sel: focal environmental variables used to define the primary constrained axis.covariates: conditioning variables used to control background structure.If samples were collected along a known gradient, that gradient or its associated variables should usually be placed in sel, with background variables in covariates.
sel = "Temperature"
covariates = c("pH", "NDVI")
If the dominant environmental structure is unclear, inspect correlations or PCA loadings first, then define sel and covariates according to the ecological hypothesis. Avoid using highly collinear predictors in ways that make the constrained axis difficult to interpret.
Use GAMs when the question is: for each taxon, where is the fitted response optimum along a selected gradient, and how wide is the response curve?
otu_gam <- plant_otu[rowSums(plant_otu > 0) >= 20, ]
gam_df <- gam_fit_model(
otu = otu_gam,
env = plant_env,
env_var = "AMT",
data_type = "count",
count_family = "nb",
use_offset = TRUE,
min_prev = 0.10,
min_total = 20,
k_spline = 5,
n_grid = 100,
verbose = FALSE
)
head(gam_df)
Plot a response curve for one taxon:
gam_plot <- gam_plot_species(
otu = plant_otu,
env = plant_env,
env_var = "AMT",
otu_id = gam_df$OTU[1],
data_type = "count",
count_family = "nb",
add_ci = TRUE
)
gam_plot$plot
gam_plot$optimum_env
gam_plot$breadth50
Aggregate GAM-derived breadth to sample level:
site_gam_width <- gam_calc_sitewidth(
otu = plant_otu,
niche_df = gam_df,
width_col = "breadth50",
weight_mode = "auto"
)
head(site_gam_width)
Classical Levins and Shannon breadth can be calculated by treating samples as discrete states:
width_both <- niche_width_calc(
otu = plant_otu,
env = plant_env,
method = "both",
standardize = TRUE,
min_occ = 3,
min_abund = 5
)
head(width_both)
EcoNiche also provides a gradient-binned Levins implementation:
levins_binned <- levins_calc_binned(
otu = plant_otu,
env = plant_env,
axis_var = "AMT",
nbin = 8,
bin_method = "equal_freq",
agg_fun = "mean",
otu_mode = "auto",
min_occ = 3,
min_abund = 5
)
head(levins_binned)
The binned implementation makes classical Levins' breadth more comparable with gradient-based analyses, but it remains a discretized approximation. It should be interpreted as a discrete-state reference metric rather than as a fully continuous estimate of niche breadth.
Community-level binned Levins breadth can be visualized along the same environmental gradient:
levins_group <- levins_calc_group(
otu = plant_otu,
env = plant_env,
levins_df = levins_binned,
grad = "AMT",
width_col = "levins_Bstd",
method = "loess",
make_plot = TRUE
)
head(levins_group$data)
levins_group$plot
colnames(otu) should match rownames(env).use_offset = TRUE to account for sample-level total abundance.A vignette under vignettes/ demonstrates the built-in plant workflow.
To build vignettes locally:
install.packages(c("knitr", "rmarkdown"))
devtools::build_vignettes()
CCA / partial CCA:
cca_workflow(), cca_workflow_gradient(), cca_workflow_group()
cca_prep_env(), cca_fit_ordination()
cca_calc_species(), cca_calc_gradient()
cca_calc_group(), cca_plot_group_env()
GAM:
gam_fit_model(), gam_plot_species(), gam_calc_sitewidth()
Levins and Shannon:
niche_width_calc()levins_calc_binned(), levins_calc_group(), levins_plot_pos_width()
If you use EcoNiche in a publication, please cite the software and include the version:
Shuotao Zhou, Kai Feng, Jiaying Li, Qing He, Shang Wang, Si Luo, Qiulong Hu, Shaolong Wu, Ye Deng, Quantifying niche breadth across environmental gradients using EcoNiche, Journal of Plant Ecology, 2026;, rtag167, https://doi.org/10.1093/jpe/rtag167
Issues and pull requests are welcome. When reporting a bug, please include:
sessionInfo(),otu and env,MIT License. See LICENSE.