The ecoTolerance package is designed to calculate two key indices for ecological studies involving species occurrences:
Road Tolerance Index (RTI)
Human Footprint Tolerance Index (HFTI)
These indices enable researchers and conservationists to assess how tolerant different species are to roads and human footprint, respectively. The package is particularly useful in biodiversity and conservation biology studies, and is part of an ongoing PhD thesis focused on amphibian species in Brazil.
Why use ecoTolerance?
Automates data cleaning (removal of duplicates, filtering of spatially nearby points).
Integrates spatial data (road networks, human footprint rasters).
Provides reproducible and consistent calculations of RTI and HFTI.
Offers built-in functions to produce maps and density plots for all species.
Supports both internal example data (Brazilian roads + human footprint rasters) and external user-supplied layers (shapefiles & rasters from any region).
Data Preprocessing
The function process_occurrences() converts a data frame of
raw occurrences (columns: species, longitude,
latitude) into a sf object, removes exact
duplicates, and optionally filters out occurrences within a user-defined
buffer to avoid pseudo-replication in ecological analyses.
Road Tolerance Index (RTI)
The function calculate_RTI() computes RTI for each record
based on the distance to the nearest road and a reference distance, both
in km. By default:
The function returns an sf object of occurrences with a
new colum RTI_value and a data frame of median RTI
per species.
Human Footprint Tolerance Index (HFTI)
The function calculate_HFTI() calculates HFTI based on the
value of human footprint in a buffer around each point. Bt default, HFTI
is:
where Human Footprint Valueiis
the average human footprint raster value within a buffer (e.g. 1km) of
occurrence i, and divisor (default = 50) normalizes those
values to 0 - 1. calculate_HFTI() returns an
sf object of occurrences with a new column
HFTI_value and an data frame of median HFTI per
species.
Single-Function Workflow
compute_indices() orchestrates all steps in one call:
process_occurrences().calculate_RTI().calculate_HFTI().It returns a list containing:
RTI: data frame of RTI per species.
HFTI: data frame of HFTI per species.
indices: combined data frame (species |
RTI | HFTI)
processed_data: the final sf with
columns RTI_value and HFTI_value for each
occurrence.
Single-Function Workflow
The function generate_all_reports() takes the output of
compute_indices(), a shapefile of the study area, and an
output directory. It automatically:
Creates a file indices_por_especie.csv (with columns
species, RTI and HFTI).
For each unique species in processed_data, generates four PNG figures:
Map of RTI (occurrence points colored by
RTI_value).
Map of HFTI (occurrence points colored by
HFTI_value)
Density plot of RTI (with a vertical line at the median).
Density plot of HFTI (with a vertical line at the median).
All files are saved in the user-specified
out_dir.
Use Internal or External Spatial Layers
By default, compute_indices() calls internal helper
functions load_roads() and
load_human_footprint() to read example layers (Brazil roads
+ Brazil human footprint ot toy data). You can also supply your own
shapefiles and rasters by “monkey-patching” those two functions in your
script, so that no internal code of the package needs to be
changed.
To install the development version from your local repository, you can use:
Make sure you have the required packages installed (sf,
raster, dplyr, stats)
By default, ecoTolerance runs in “Toy Mode”. It uses a small, lightweight dataset included in the package.
The compute_indices() function uses
data_type= "toy" by default.
To automatically save maps, plots, and CSVs for every species:
# 1) Shapefile of the study area (Optional, for context in the map)
# For this example, we create a dummy box, but you would load your shapefile.
library(sf)
study_area_sf <- st_as_sf(
data.frame(id = 1),
geometry = st_sfc(st_polygon(list(rbind(c(-39, -13), c(-38, -13), c(-38, -12), c(-39, -12), c(-39, -13))))),
crs = 4326
)
# 2) Output directory
output_dir <- tempdir() # Or "C:/MyResults"
# 3) Generate all maps & plots
generate_all_reports(
result = result,
area_shapefile = study_area_sf, # Can also be a path to a .shp file
out_dir = output_dir
)To perform a real analysis covering the entire Brazilian territory,
you simply need to change the data_type argument to
"full".
When you run this for the first time, the package will automatically:
Download the full Brazilian roads shapefile and Human Footprint raster from the Zenodo repository (~60 MB).
Save these files in a persistent cache on your computer (tools::R_user_dir).
Load them for analysis.
Future runs will load directly from the cache, so you only download once.
# Real occurrence data anywhere in Brazil
real_data <- data.frame(
species = c("Frog X", "Frog Y"),
longitude = c(-45.32, -40.10),
latitude = c(-15.20, -18.50)
)
# Run with full dataset
# Note: The first time you run this, it will take a few minutes to download.
result_full <- compute_indices(
data = real_data,
data_type = "full", # <--- This triggers the download/cache load
ref_dist = 3.5
)If your study area is outside Brazil, or you have custom high-resolution data, you can supply your own layers using the “monkey-patch” approach.
library(ecoTolerance)
# 1) Read your own data
occ_data <- read.csv("path/to/my_occurrences.csv")
# 2) Overwrite load_roads() and load_human_footprint() in your global environment.
# IMPORTANT: They must accept arguments (like 'type'), even if you don't use them.
load_roads <- function(type="toy") {
# Argument 'type' is ignored here, we just return our custom file
roads_sf <- sf::st_read("path/to/my_custom_roads.shp", quiet = TRUE)
if (sf::st_crs(roads_sf)$epsg != 4326) {
roads_sf <- sf::st_transform(roads_sf, crs = 4326)
}
return(roads_sf)
}
load_human_footprint <- function(type="toy") {
footprint_raster <- raster::raster("path/to/my_custom_footprint.tif")
return(footprint_raster)
}
# 3) Now call compute_indices()
# It will use your custom functions instead of the package internals
result_custom <- compute_indices(
data = occ_data
)If you prefer to run step-by-step instead of using
compute_indices(), here is how the package works
internally.
Run process_occurrences() to remove exact duplicates and
optionally filter out records closer than 1km:
processed_data <- process_occurrences(
data = sample_data,
remove_duplicates = TRUE,
buffer_km = 1
)remove_duplicates = TRUE removes identical
coordinates for the same species.
buffer_km = 1 ensures only one record per species
within a 1 km radius.
processed_data is now an sf object in
EPSG:4326.
If you want to calculate RTI and HFTI in separate steps, you can do:
# 1) Load internal example layers (or full)
roads <- load_roads(type = "toy")
footprint <- load_human_footprint(type = "toy")
# 2) Calculate RTI
rti_result <- calculate_RTI(
occurrences = processed_data,
roads = roads,
ref_dist = 3.5
)
# 3) Calculate HFTI
# Note: we use rti_result$data because it now contains the RTI values
hfti_result <- calculate_HFTI(
occurrences = rti_result$data,
footprint = footprint,
divisor = 50,
buffer_m = 1000
)
# 4) Inspect the outputs
head(rti_result$RTI) # median RTI per species
head(hfti_result$HFTI) # median HFTI per speciesIf you want to visualize the computed indices spatially, you can do:
library(ggplot2)
# For RTI:
ggplot(hfti_result$data) +
geom_sf(aes(color = RTI_value)) +
scale_color_viridis_c(name = "RTI") +
theme_minimal() +
ggtitle("Road Tolerance Index (RTI) per Occurrence")
# For HFTI:
ggplot(hfti_result$data) +
geom_sf(aes(color = HFTI_value)) +
scale_color_viridis_c(name = "HFTI") +
theme_minimal() +
ggtitle("Human Footprint Tolerance Index (HFTI) per Occurrence")Buffer distance (buffer_km): adjust
according to how fine_scaled your occurrence data is. A larger buffer
removes points too close to each other withing that radius.
Reference Distance (ref_dist) for
RTI: choose a value (in km) that makes sense
biologically. Amphibians might need a larger reference distance
(e.g. 3.5km) than plants (e.g. 1.5km) for instance.
Divisor for HFTI: set divisor for
the maximum possible raster value. If your raster ranges 0-100, use
divisor = 100. The default in the package is 50.
CRS Consistency: calculate_RTI()
expects both occurrences and roads in EPSG:4326 (latitude/longitude).
Internally, st_distance() does a geodetic calculation in
meters. calculate_HFTI() assumes the human footprint raster
is in a projected CRS (e.g. UTM) or at least geographic CRS in meters.
If in degrees, the buffer will be interpreted in degrees (not
recommended). The vignette examples always reproject to 4326 if
necessary, but ideally your raster should already be in a metric
projection.
The ecoTolerance package streamlines the process of computing road and human footprint tolerance indices for ecological and conservation studies. By combining robust data processing with reproducible spatial calculations, it aids researchers in understanding species’ responses to anthropogenic disturbances.
Citation / Reference
Please cite this package or the relevant paper if it is part of your paper.
For academic citation, you can use:
We thank all the collaborators and advisors involved in this research.
This package is part of an ongoing PhD thesis at Programa de Pós-Graduação em Ecologia: Teoria, Aplicação e Valores of Universidade Federal da Bahia.