yaml

---
title: "letsHerp: An R Interface to the Reptile Database"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{letsHerp}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

### **An Interface to the Reptile Database**

This package was developed to facilitate the processes of reptile nomenclature update based on a search for species synonyms according to [The Reptile Database](https://reptile-database.reptarium.cz) website (Uetz et al., 2025).

Currently, the package accesses many species information from the Reptile Database using R interface.

I hope it to be useful to people trying to match databases from different sources (IUCN, species traits database, etc), or trying to get summaries from a given higher taxa or region (e.g.: Snakes from Brazil). But it can also just print single species information directly in R.

Any feedback, suggestion or request are welcome!

### **Download**

A CRAN submission is in progress; until then, the development version can be installed from GitHub.

To install the stable version of this package, users must run:

```{.r}
# Install development version from GitHub
# install.packages("devtools")
devtools::install_github("joao-svalencar/letsHerp")

library(letsHerp)
```

### **List of functions and examples**
**Function `herpSearch`:**

Retrieves species information from The Reptile Database using a binomial name.
```{.r}
# single species:
herpSearch(binomial = "Apostolepis adhara")

# If user wants to check the list of references related to species, as listed in RDB:
herpSearch(binomial = "Bothrops pauloensis", ref=TRUE)
```

`herpSearch()` supports synonym-based queries. If the provided binomial does not match any currently valid species name, the function automatically passes the query to `herpAdvancedSearch(synonym = binomial)`. In such cases, if the synonym can be unambiguously resolved to a valid species, the function will return the corresponding species information. Otherwise, it provides a link to a list of all species that include the queried synonym in their synonymy (which can be accessed using `herpSpecies(link)`)

**Function `herpAdvancedSearch`:**

Creates a link for a page as derived from an Advanced Search in RD (multiple species in a page):
```{.r}
# create multiple species link:
link_boa <- herpAdvancedSearch(genus = "Boa") #returns a link to a list of all Boa species

link_apo <- herpAdvancedSearch(genus = "Apostolepis") #returns a link to a list of all Apostolepis species

link <- herpAdvancedSearch(higher = "snakes", location = "Brazil") #returns a link to a list of all snake species in Brazil

link <- herpAdvancedSearch(year = "2010 OR 2011 OR 2012") #returns a link to a list of all species described from 2010 to 2012
```

`herpAdvancedSearch(synonym = "example")` will return the species information directly (via `herpSearch("example")`) if the synonym uniquely matches a single valid species.

**Function `herpSpecies`:**

Retrieve species data from the species link created by `herpAdvancedSearch`. User can also copy and paste the url from a RD webpage containing the list of species derived from an advanced search. It includes higher taxa information, authors, year of description, and the species url. By default this function uses parallel processing, with default set to leave just one core available. **NOTE:** Parallel processing may affect system performance. Adjust the number of cores according to your needs. If user wants to use just one core, there are options for backup saving based on the `checkpoint` argument.

```{.r}
# sample multiple species data:
#Returns higher taxa information and species url:
boa <- herpSpecies(link_boa, taxonomicInfo = TRUE, getLink = TRUE) #link from herpAdvancedSearch(genus = "Boa")

#example 2
apo <- herpSpecies(link_apo, taxonomicInfo = TRUE, getLink = TRUE) #link from herpAdvancedSearch(genus = "Apostolepis")

#Returns only species url - Faster and recommended for large datasets:
boa <- herpSpecies(link_boa, taxonomicInfo = FALSE, getLink = TRUE) #link from herpAdvancedSearch(genus = "Boa")

#example 2
apo <- herpSpecies(link_apo, taxonomicInfo = FALSE, getLink = TRUE) #link from herpAdvancedSearch(genus = "Apostolepis")

#With checkpoint and backups (only without parallel sampling: a lot slower but safer):
path <- "path/to/save/backup_file.rds" #not to run just example 
apo <- herpSpecies(link_apo, taxonomicInfo = FALSE, getLink = TRUE, checkpoint=6, backup_file=path) #link from herpAdvancedSearch(genus = "Apostolepis")
```

⚠️ **Note:**

All console messages, warnings, and progress updates can be silenced. However, `herpSpecies()` issues a helpful warning if any species information fails to be retrieved, along with instructions on how to access those entries from the function output.

**Function `herpSynonyms`:**

Samples species synonyms using a data frame with species names and the species link (e.g.: the result of `herpSpecies(link, getLink=TRUE)`). By default this function uses parallel processing, with default set to leave just one core available. **NOTE:** Parallel processing may affect system performance. Adjust the number of cores according to your needs. If user wants to use just one core, there are options for backup saving based on the `checkpoint` argument.

```{.r}
# sample species synonyms
boa_syn <- herpSynonyms(boa)

#example 2
apo_syn <- herpSynonyms(apo)
```

⚠️ **Note:**

All console messages, warnings, and progress updates can be silenced. However, `herpSynonyms()` issues a helpful warning if any species information fails to be retrieved, along with instructions on how to access those entries from the original data frame.

The complex `regex` pattern used to sample synonyms from The Reptile Database is quite efficient, but still samples about 0.2% in an incorrect format. Most cases represent unusual nomenclature so users might not face any problems trying to match current valid names. In any case, I fixed (potentially) all unusual synonym formats in the internal dataset `allSynonyms` (last update: 23rd May, 2025)

**Function `herpSync`:**

Inspired in function aswSync from package [AmphiNom](https://github.com/hcliedtke/AmphiNom) (Liedtke, 2018), this function compares a given list of species (e.g.: IUCN, or a regional list) with the list of species synonyms and returns a tidy comparison allowing faster nomenclature check.

```{.r}
# comparing synonyms:
boa_list <- c("Vieira-Alencar authoristicus",
              "Boa atlantica",
              "Boa diviniloqua",
              "Boa imperator",
              "Boa constrictor longicauda")

herpSync(boa_list, boa_syn)

#example 2:
apo_list <- c("Vieira-Alencar authorisensis",
              "Apostolepis ambiniger",
              "Apostolepis cerradoensis",
              "Elapomorphus assimilis",
              "Apostolepis tertulianobeui",
              "Apostolepis goiasensis")

herpSync(apo_list, apo_syn)
```

The column "Reptile_Database" shows current valid name according to The Reptile Database.

Special attention is needed to columns "status" and "warnings":

**status:**

- "up_to_date" -  Species name provided is the current valid name found in The Reptile Database
 
- "updated" - Species name provided is a synonym, and the current valid name is reported unambiguously.

- "ambiguous" - Species name provided is considered a synonym of more than one current valid species, likely from a split in taxonomy. The synonym from query might also be found in the list of the current valid names, and can be assigned as valid on the fly using `interactive = TRUE` but see the example above for *Boa diviniloqua*.

- "name_not_found" - Species name provided in query is not a current valid name nor synonym according to The Reptile Database. This status could be derived from a typo within species name. A very rare situation where this status can pop up is when the current valid name is updated in the query but is not found in the list of synonyms.

**warnings:**

- "duplicated" - Currently, this is the only warning the user will get from `herpSync`. It means that multiple names in the query are now considered synonyms of a single valid species, likely from a synonymization. In the example above both *Boa diviniloqua* and *Boa constrictor longicauda* are considered synonyms of *Boa constrictor*.

⚠️ **ATTENTION!**⚠️ 

`letsHerp` does not make taxonomic decisions. The package sample species current valid names and known synonyms but the decision upon which nomenclature to use relies on user expertise.

### **Internal datasets**

- The package counts with a full list of current valid species (`allReptiles` - 12,440 species) with their respective higher taxa information (updated to May 23rd, 2025);

- A dataset with all unique synonyms for each current valid species (`allSynonyms` - 53,159 entries - updated to May 23rd, 2025); 

- Another synonyms dataset with all entries considering their respective references (`allSynonymsRef` - 110,413 entries - updated to May 23rd, 2025).

### **How to Cite**

To cite this package in publications, run:

```r
citation("letsHerp")
```

### **References**
Liedtke, H. C. (2018). AmphiNom: an amphibian systematic tool. Systematics and Biodiversity, 17(1) 1-6. https://doi.org/10.1080/14772000.2018.1518935

Uetz, P., Freed, P, Aguilar, R., Reyes, F., Kudera, J. & Hošek, J. (eds.) (2025). [The Reptile Database](http://www.reptile-database.org)

### **Author:**
João Paulo dos Santos Vieira de Alencar

Email: joaopaulo.valencar@gmail.com

[Orcid](https://orcid.org/0000-0001-6894-6773) | [ResearchGate](https://www.researchgate.net/profile/Joao-Paulo-Alencar)
