Warning: package 'terra' was built under R version 4.4.3
Warning: package 'data.table' was built under R version 4.4.3
Warning: package 'sf' was built under R version 4.4.3
1 Get native ranges
This module subsets IUCN species range maps to retain only those species with mountain occurrence records. We will work on the amphibian occurrences data from previous tutorials as an example.
2 Load data
We read the amphibian occurrences data to extract the species names:
Code
# Load occurrences to extract spp names# Read only needed columns (Here we only need the species names)amphibians_in_mountains_df <-fread(file.path(local_folder, "amphibians_in_mountains.csv"),select =c("taxon")) # Keep only valid names Remove NA values (total 82 spp) spp.names <-unique(na.omit(amphibians_in_mountains_df$taxon))
3 Load IUCN species distribution maps
Here we load the amphibian distribution maps from IUCN. Note that amphibian maps are split into two shapefiles, so we will need to process both files and then combine them:
We now keep only the species with mountain occurrence records and homogenize the attribute tables in order to combine them:
Code
# Identify all unique column names across all SpatVectorsall_colnames <-unique(unlist(lapply(filtered_amphs, names)))# Find intersection of column namescommon_cols <-Reduce(intersect, lapply(filtered_amphs, names))# Subset all vectors to common columns and combinefiltered_amphs <-do.call(rbind, lapply(filtered_amphs, function(v) v[, common_cols]))spp_polygs <-unique(filtered_amphs$sci_name)
3.1 Save results
The results can be saved as shapefiles for further analysis. Here we save the amphibian polygons:
Code
# Save as shapefile (creates 3 files: .shp, .shx, .dbf)writeVector(filtered_amphs, "../INPUTS/amphibian_distribution_polygons.shp",filetype ="ESRI Shapefile", overwrite=TRUE)save.image("3_SubsetIUCNpolygs.RData")
4 Estimate distance to native ranges
This section calculates the minimum distance from each occurrence record to the species’ native range polygon. First we need to load the function ‘distance_to_native’ to calculate distances. The function is hosted at the figshare repository of this project:
Now we can estimate the distance to native ranges for all species in the dataset. This process can take some time depending on the number of species and records:
The output data frame ‘dist_to_native_df’ contains the original occurrence data along with a new column ‘min_distance_nat_range’ indicating the minimum distance (in kilometers) from each record to the nearest native range polygon.
4.1 Extract alien records by distance thresholds
Users can now set a distance threshold to determine which records to consider as alien. For example, to consider records beyond 50 km from the native range as alien:
Code
# Alien records beyond 50 km from native rangedist_to_native_df$status <-ifelse(dist_to_native_df$min_distance_nat_range <=50,"native","non-native")
Reference
García-Rodríguez, A., Lenzner, B., Velasco, J.A. et al. The global distribution patterns of alien vertebrate richness in mountains. Nat Commun 16, 1977 (2025). https://doi.org/10.1038/s41467-025-57214-w
Session information
Click to see
Warning in system2("quarto", "-V", stdout = TRUE, env = paste0("TMPDIR=", :
running command '"quarto"
TMPDIR=C:/Users/garciaa/AppData/Local/Temp/Rtmp6XHWjJ/file16cc57daa20 -V' had
status 1
---title: Compute distance to native rangessubtitle: RAVeMauthor: Adrian García-Rodríguez, David Umhauer & Marcelo Araya-Salasdate: "`r Sys.Date()`"toc: truetoc-depth: 3toc-location: leftnumber-sections: truehighlight-style: pygmentsformat: html: df-print: kable code-fold: show code-tools: true css: qmd.csseditor_options: chunk_output_type: console---```{r set root directory}#| eval: true#| echo: false# install knitr package if not installedif (!requireNamespace("knitr", quietly = TRUE)) { install.packages("knitr")}# set working directory knitr::opts_knit$set(root.dir = "..")``````{r setup style}#| message: false#| warning: false#| echo: false# options to customize chunk outputsknitr::opts_chunk$set( # tidy.opts = list(width.cutoff = 65), # tidy = TRUE, message = FALSE )local_folder <- "./data/processed" ```<!-- skyblue box -->::: {.alert .alert-info}# Purpose {.unnumbered .unlisted}- Compute distance to native ranges for species occurrences in mountains :::First we load the required packages:```{r load packages}#| eval: true# install packages if not installedif (!requireNamespace("sketchy", quietly = TRUE)) { install.packages("sketchy")}packages <- c("terra", "data.table", "doParallel", "sf", "sp", "dplyr", "rgdal")# install/ load packagessketchy::load_packages(packages = packages)```# Get native rangesThis module subsets IUCN species range maps to retain only those species with mountain occurrence records. We will work on the amphibian occurrences data from previous tutorials as an example.# Load dataWe read the amphibian occurrences data to extract the species names:```{r load-data}# Load occurrences to extract spp names# Read only needed columns (Here we only need the species names)amphibians_in_mountains_df <- fread(file.path(local_folder, "amphibians_in_mountains.csv"), select = c("taxon")) # Keep only valid names Remove NA values (total 82 spp) spp.names <- unique(na.omit(amphibians_in_mountains_df$taxon)) ```# Load IUCN species distribution mapsHere we load the amphibian distribution maps from IUCN. Note that amphibian maps are split into two shapefiles, so we will need to process both files and then combine them:```{r process-multipart-files}#| eval: falseamphs1 <- vect(paste0("../INPUTS/IUCNpolygsRAW/AMPHIBIANS_PART1.shp"))amphs2 <- vect(paste0("../INPUTS/IUCNpolygsRAW/AMPHIBIANS_PART1.shp"))filtered_amphs1 <- amphs1[amphs1$sci_name %in% spp.names, ]filtered_amphs2 <- amphs2[amphs2$sci_name %in% spp.names, ]filtered_amphs <- list(filtered_amphs1, filtered_amphs2)```We now keep only the species with mountain occurrence records and homogenize the attribute tables in order to combine them:```{r process-multipart-files 2}#| eval: false# Identify all unique column names across all SpatVectorsall_colnames <- unique(unlist(lapply(filtered_amphs, names)))# Find intersection of column namescommon_cols <- Reduce(intersect, lapply(filtered_amphs, names))# Subset all vectors to common columns and combinefiltered_amphs <- do.call(rbind, lapply(filtered_amphs, function(v) v[, common_cols]))spp_polygs <- unique(filtered_amphs$sci_name)```## Save resultsThe results can be saved as shapefiles for further analysis. Here we save the amphibian polygons:```{r save-results}#| eval: false# Save as shapefile (creates 3 files: .shp, .shx, .dbf)writeVector(filtered_amphs, "../INPUTS/amphibian_distribution_polygons.shp", filetype = "ESRI Shapefile", overwrite=TRUE)save.image("3_SubsetIUCNpolygs.RData")```<!-- add packages used, system details and versions --># Estimate distance to native rangesThis section calculates the minimum distance from each occurrence record to the species' native range polygon. First we need to load the function 'distance_to_native' to calculate distances. The function is hosted at the [figshare repository of this project](https://figshare.com/s/ca1f543aa0b13b07d22a):```{r}#| eval: falsesource("https://figshare.com/ndownloader/files/58805263")```Now we can estimate the distance to native ranges for all species in the dataset. This process can take some time depending on the number of species and records:```{r prepare-data}#| eval: false# Adjust object names for analysisoccs.df <- Dasco.occs2sp.names <- unique(occs.df$taxon)dist_to_native_list <- pblapply(1:length(sp.names), distance_to_native)# Remove NULL entries from failed processingdist_to_native_list <- dist_to_native_list[!sapply(dist_to_native_list, is.null)]# Combine successful resultsdist_to_native_df <- do.call(rbind, dist_to_native_list)```The output data frame 'dist_to_native_df' contains the original occurrence data along with a new column 'min_distance_nat_range' indicating the minimum distance (in kilometers) from each record to the nearest native range polygon.## Extract alien records by distance thresholdsUsers can now set a distance threshold to determine which records to consider as alien. For example, to consider records beyond 50 km from the native range as alien:```{r}#| eval: false# Alien records beyond 50 km from native rangedist_to_native_df$status <-ifelse(dist_to_native_df$min_distance_nat_range <=50,"native","non-native")```## Reference {.unnumbered .unlisted}García-Rodríguez, A., Lenzner, B., Velasco, J.A. et al. The global distribution patterns of alien vertebrate richness in mountains. Nat Commun 16, 1977 (2025). https://doi.org/10.1038/s41467-025-57214-w## Session information {.unnumbered .unlisted}<details> <summary>Click to see</summary>```{r session info}#| echo: false# if devtools is installed use devtools::session_info()if (requireNamespace("devtools", quietly = TRUE)) { devtools::session_info()} else { sessionInfo()}```</details>