ssarp
Repo for the R Package ssarp (Species-/Speciation-Area Relationship Projector)
Science Score: 49.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
○CITATION.cff file
-
✓codemeta.json file
Found codemeta.json file -
✓.zenodo.json file
Found .zenodo.json file -
✓DOI references
Found 1 DOI reference(s) in README -
✓Academic publication links
Links to: biorxiv.org -
○Academic email domains
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (19.8%) to scientific vocabulary
Last synced: 6 months ago
·
JSON representation
Repository
Repo for the R Package ssarp (Species-/Speciation-Area Relationship Projector)
Basic Info
- Host: GitHub
- Owner: kmartinet
- Language: R
- Default Branch: main
- Homepage: https://kmartinet.github.io/ssarp/
- Size: 15 MB
Statistics
- Stars: 4
- Watchers: 1
- Forks: 2
- Open Issues: 1
- Releases: 0
Created about 3 years ago
· Last pushed 7 months ago
Metadata Files
Readme
Changelog
Contributing
Codemeta
README.Rmd
---
output: github_document
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```
# ssarp
[](https://codecov.io/gh/kmartinet/ssarp?branch=main)
[](https://github.com/kmartinet/ssarp/actions/workflows/R-CMD-check.yaml)
[](https://www.repostatus.org/#active)
[](https://github.com/ropensci/software-review/issues/685)
`ssarp` (Species-/Speciation-Area Relationship Projector) is an R package that provides a suite of functions to help users **create speciation- and species-area relationships for island-dwelling taxa** using occurrence data from GBIF (Global Biodiversity Information Facility) or the user's own occurrence data.
Species- and speciation-area relationships are useful for determining whether biodiversity is distributed in an unusual way in a given island system (e.g., species richness decreasing as islands get larger instead of increasing). An unusual trend in these relationships may be indicative of habitat loss or a negative impact of non-native species.
Please find the [bioRxiv preprint of the manuscript associated with *ssarp* here!](https://www.biorxiv.org/content/10.1101/2024.12.31.630948v1)
## Installation
To install *ssarp*, use the "install_github" function from the *devtools* package:
``` r
# install.packages("devtools")
library(devtools)
install_github("kmartinet/ssarp")
```
## Suppressing Messages
To suppress all messages output by *ssarp*, run
``` r
options(ssarp.silent = TRUE)
```
before using any of *ssarp*'s functions.
## Example: Creating a Species-Area Relationship
A species-area relationship (SAR) visualizes the relationship between species richness (the number of species) and the area of the land mass on which the species live. This brief example covers the *ssarp* workflow for creating a SAR, and more detailed explanations of the code and methods can be found [in the Articles on the ssarp pkgdown website](https://kmartinet.github.io/ssarp/index.html).
In order to construct a species-area relationship with *ssarp*, we will:
- Gather occurrence data from GBIF
- Filter out invalid occurrence records
- Find areas of pertinent land masses
- Create a species-area relationship
#### Step 1: Gather occurrence data from GBIF
In this step, we will find the unique identifying key associated with a taxon of interest (the lizard genus *Anolis* in this case) and use that key to access occurrence points for that taxon from GBIF. We will restrict the returned occurrence records to the Caribbean islands using the "geometry" parameter in the `rgbif::occ_search()` function.
```{r, warning = FALSE, message = FALSE}
library(rgbif)
query <- "Anolis"
rank <- "Genus"
suggestions <- rgbif::name_suggest(q = query, rank = rank)
# The correct key is the first element in the first row
key <- as.numeric(suggestions$data[1,1])
# Print key
key
```
The GBIF key for *Anolis* is 8782549. We will use this key, along with a Well-Known Text (WKT) polygon around Caribbean islands, to get data for *Anolis* from GBIF using the `rgbif::occ_search()` function.
```{r, warning = FALSE, message = FALSE}
# Get data for Anolis from GBIF in a specified polygon around Caribbean islands
dat <- rgbif::occ_search(taxonKey = key,
limit = 10000,
hasCoordinate = TRUE,
geometry = 'POLYGON((-84.8 23.9, -84.7 16.4, -65.2 13.9, -63.1 11.0, -56.9 15.5, -60.5 21.9, -79.3 27.8, -79.8 24.8, -84.8 23.9))')
# Print the first 5 lines of dat
head(dat, n = 5)
```
The "dat" dataframe above includes the first 10,000 records from GBIF for *Anolis* within a specified polygon around the Caribbean islands.
#### Step 2: Filter out invalid occurrence records
Now that we have a dataframe that includes the first 10,000 records for *Anolis* within a specified polygon around the Caribbean islands, we will filter that data to include only occurrence records that are on land. Some occurrence records might have GPS points that are in the ocean instead of on an island, so it is important to exclude these invalid records.
```{r}
# Find land mass names and exclude records not on land
land_dat <- ssarp::find_land(occurrences = dat)
# Print first 5 lines of land_dat
head(land_dat, n = 5)
```
The "land_dat" dataframe above is a filtered version of the "dat" dataframe that we created by gathering data from GBIF. The "land_dat" dataframe includes occurrence records with GPS points that fall on a land mass, along with the locality information for that land mass.
The locality information is split across three columns: “First,” “Second,” and “Third.” The mapping utilities that *ssarp* uses sometimes output different levels of specificity for locality information (up to three different levels), so these columns provide space for these different levels. The island name that we are interested in will be in the last filled-in column of the three. For example, if there are two columns of locality information for a given occurrence record, the island name will be in the second. If there is only one column of locality information, it will contain the island name (as with Puerto Rico and Antigua above). If all columns have NA, the occurrence record is invalid and will be filtered out in the next step.
#### Step 3: Find areas of pertinent land masses
Next, we will use the dataframe of occurrence records with their associated land mass names (the "land_dat" object created above) with the `ssarp::find_areas()` function to find the area of each land mass.
```{r, warning = FALSE, message = FALSE}
# Use the land mass names to get their areas
area_dat <- ssarp::find_areas(occs = land_dat)
# Print the first 5 lines of area_dat
head(area_dat, n = 5)
```
The "area_dat" dataframe includes records with GPS points that are associated with a land mass, along with the areas of those land masses (in m^2).
#### Step 4: Create the species-area relationship
Finally, we will generate the SAR using the `ssarp::create_SAR()` function. The `ssarp::create_SAR()` function creates multiple regression objects with breakpoints up to the user-specified “npsi” parameter. For example, if “npsi” is two, `ssarp::create_SAR()` will generate regression objects with zero (linear regression), one, and two breakpoints. The function will then return the regression object with the lowest AIC score. The “npsi” parameter will be set to one in this example. Note that if linear regression (zero breakpoints) is better-supported than segmented regression with one breakpoint, the linear regression will be returned instead.
```{r}
ssarp::create_SAR(occurrences = area_dat, npsi = 1)
```
This is the species-area relationship (SAR) for Anolis including island-based occurrences within a polygon around Caribbean islands from the first 10,000 records for the genus in GBIF! The best-fit model was a segmented regression with one breakpoint. The R console will also output statistical information about the model.
### Workflow Summary for using data from GBIF to create a species-area relationship plot
1. Use `rgbif` to gather occurrence records, or input your own dataframe of occurrence records.
2. Use `find_land(occ, fillgaps)` with the dataframe obtained in Step 1 to figure out the names of landmasses using the occurrence record GPS points and the [*maps* R package](https://cran.r-project.org/web/packages/maps/index.html). Setting the "fillgaps" parameter to `TRUE` will enable the use of [Photon API](https://photon.komoot.io/) to fill in any missing landmass names left by the *maps* R package.
3. Use `find_areas(occ, area_custom)` with the dataframe obtained in Step 2 to match the landmass names to a dataset that includes names of most islands on the planet and their areas. If the user would like to use a custom island area dataset instead of the built-in one, the "area_custom" parameter can be set to the name of the custom island area dataframe.
3a. If you'd like to only include occurrence records from islands, you can remove continental records by using `remove_continents(occ)` with the dataframe returned by `find_areas()`
5. Use `create_SAR(occ, npsi)` with the dataframe obtained in Step 3 to create a species-area relationship plot that reports information important to the associated regression. The "npsi" parameter indicates the maximum number of breakpoints the user would like to compare for model selection. The returned model and plot correspond with the best-fit model.
### Workflow summary for using data from GBIF and a user-provided phylogenetic tree to create a speciation-area relationship plot
1. Use `rgbif` to gather occurrence records, or input your own dataframe of occurrence records.
2. Use `find_land(occ, fillgaps)` with the dataframe obtained in Step 1 to figure out the names of landmasses using the occurrence record GPS points and the [*maps* R package](https://cran.r-project.org/web/packages/maps/index.html). Setting the "fillgaps" parameter to `TRUE` will enable the use of [Photon API](https://photon.komoot.io/) to fill in any missing landmass names left by the *maps* R package.
3. Use `find_areas(occ, area_custom)` with the dataframe obtained in Step 2 to match the landmass names to a dataset that includes names of most islands on the planet and their areas. If the user would like to use a custom island area dataset instead of the built-in one, the "area_custom" parameter can be set to the name of the custom island area dataframe.
3a. If you'd like to only include occurrence records from islands, you can remove continental records by using `remove_continents(occ)` with the dataframe returned by `find_areas()`
4. Use either `estimate_DR(tree, label_type, occ)` or `estimate_MS(tree, label_type, occ)` with your own phylogenetic tree that corresponds with the taxa signified in previous steps, a classifier that describes your tip labels (whether the tip labels are simply species epithets or full scientific names), and the dataframe obtained in Step 3 to add tip speciation rates using the DR statistic (Jetz et al. 2012) or the lambda calculation for crown groups from Magallόn and Sanderson (2001) respectively to the occurrence dataframe. The user may also choose to estimate tip speciation rates from a BAMM analysis (Rabosky 2014) by using `estimate_BAMM(label_type, occ, edata)` with a classifier that describes your tip labels (whether the tip labels are simply species epithets or full scientific names), the occurrence record dataframe obtained in Step 3, and a bammdata object generated by reading the event data file from a BAMM analysis with the *BAMMtools* package (Rabosky et al. 2014).
5. Use `create_SpAR(occ, npsi)` with the dataframe obtained in Step 4 to create a speciation-area relationship plot that reports information important to the associated regression. The "npsi" parameter indicates the maximum number of breakpoints the user would like to compare for model selection. The returned model and plot correspond with the best-fit model.
### Some helpful notes about well-known text (WKT) representation of geometry
When running `getData()`, the user can specify a well-known text (WKT) representation of geometry to restrict the geographic location of the returned occurrence records. The rgbif::occ_search function that `getData()` calls requires a counter-clockwise winding order for WKT. I find it helpful to think about WKT polygons in this way: imagine a square around your geographic area of interest and pick one of the corners as a starting point. The order of points in WKT format should follow counter-clockwise from the corner you picked first, and the final entry in the WKT string needs to be the same as the first entry. Additionally, while GPS points are typically represented in "latitude, longitude" format, WKT expects them in "longitude latitude" format with commas separating the points rather than individual longitude and latitude values. WKT polygons can have more specified points than included in this simple square example, and even include polygons nested within others or polygons with holes in the middle.
#### Literature Cited
- Jetz, W., Thomas, G.H, Joy, J.B., Harmann, K., & Mooers, A.O. (2012). The global diversity of birds in space and time. *Nature*, 491: 444-448.
- Magallόn, S. & Sanderson, M.J. (2001). Absolute Diversification Rates in Angiosperm Clades. *Evolution*, 55(9): 1762-1780.
- Rabosky, D.L. (2014). Automatic Detection of Key Innovations, Rate Shifts, and Diversity-Dependence on Phylogenetic Trees. PLOS ONE, 9(2): e89543.436
- Rabosky, D.L., Grundler, M., Anderson, C., Title, P., Shi, J.J., Brown, J.W., Huang, H., & Larson, J.G. (2014). BAMMtools: an R package for the analysis of evolutionary dynamics on phylogenetic trees. Methods in Ecology and Evolution, 5: 701-707.
Owner
- Login: kmartinet
- Kind: user
- Repositories: 1
- Profile: https://github.com/kmartinet
CodeMeta (codemeta.json)
{
"@context": "https://doi.org/10.5063/schema/codemeta-2.0",
"@type": "SoftwareSourceCode",
"identifier": "ssarp",
"description": "Create Species- and Speciation-Area Relationships using occurrence records or presence-absence matrices.",
"name": "ssarp: Species-/Speciation-Area Relationship Projector",
"relatedLink": "https://kmartinet.github.io/ssarp/",
"codeRepository": "https://github.com/ropensci/ssarp",
"issueTracker": "https://github.com/ropensci/ssarp/issues",
"license": "https://spdx.org/licenses/GPL-2.0",
"version": "0.5.0",
"programmingLanguage": {
"@type": "ComputerLanguage",
"name": "R",
"url": "https://r-project.org"
},
"runtimePlatform": "R version 4.5.1 (2025-06-13 ucrt)",
"author": [
{
"@type": "Person",
"givenName": "Kristen",
"familyName": "Martinet",
"email": "kmartinet@outlook.com",
"@id": "https://orcid.org/0000-0002-3905-9507"
}
],
"contributor": [
{
"@type": "Person",
"givenName": "Luke",
"familyName": "Harmon",
"@id": "https://orcid.org/0000-0002-4985-5750"
},
{
"@type": "Person",
"givenName": "Cristian",
"familyName": "Romn-Palacios",
"@id": "https://orcid.org/0000-0003-1696-4886"
}
],
"maintainer": [
{
"@type": "Person",
"givenName": "Kristen",
"familyName": "Martinet",
"email": "kmartinet@outlook.com",
"@id": "https://orcid.org/0000-0002-3905-9507"
}
],
"softwareSuggestions": [
{
"@type": "SoftwareApplication",
"identifier": "testthat",
"name": "testthat",
"version": ">= 3.0.0",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=testthat"
},
{
"@type": "SoftwareApplication",
"identifier": "rmarkdown",
"name": "rmarkdown",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=rmarkdown"
},
{
"@type": "SoftwareApplication",
"identifier": "knitr",
"name": "knitr",
"version": ">= 1.46",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=knitr"
},
{
"@type": "SoftwareApplication",
"identifier": "rgbif",
"name": "rgbif",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=rgbif"
},
{
"@type": "SoftwareApplication",
"identifier": "BAMMtools",
"name": "BAMMtools",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=BAMMtools"
},
{
"@type": "SoftwareApplication",
"identifier": "curl",
"name": "curl",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=curl"
},
{
"@type": "SoftwareApplication",
"identifier": "httptest",
"name": "httptest",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=httptest"
},
{
"@type": "SoftwareApplication",
"identifier": "spdep",
"name": "spdep",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=spdep"
},
{
"@type": "SoftwareApplication",
"identifier": "epm",
"name": "epm",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=epm"
}
],
"softwareRequirements": {
"1": {
"@type": "SoftwareApplication",
"identifier": "ape",
"name": "ape",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=ape"
},
"2": {
"@type": "SoftwareApplication",
"identifier": "checkmate",
"name": "checkmate",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=checkmate"
},
"3": {
"@type": "SoftwareApplication",
"identifier": "cli",
"name": "cli",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=cli"
},
"4": {
"@type": "SoftwareApplication",
"identifier": "Dict",
"name": "Dict",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=Dict"
},
"5": {
"@type": "SoftwareApplication",
"identifier": "dplyr",
"name": "dplyr",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=dplyr"
},
"6": {
"@type": "SoftwareApplication",
"identifier": "httr",
"name": "httr",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=httr"
},
"7": {
"@type": "SoftwareApplication",
"identifier": "mapdata",
"name": "mapdata",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=mapdata"
},
"8": {
"@type": "SoftwareApplication",
"identifier": "maps",
"name": "maps",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=maps"
},
"9": {
"@type": "SoftwareApplication",
"identifier": "reshape2",
"name": "reshape2",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=reshape2"
},
"10": {
"@type": "SoftwareApplication",
"identifier": "segmented",
"name": "segmented",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=segmented"
},
"11": {
"@type": "SoftwareApplication",
"identifier": "sf",
"name": "sf",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=sf"
},
"12": {
"@type": "SoftwareApplication",
"identifier": "stringi",
"name": "stringi",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=stringi"
},
"13": {
"@type": "SoftwareApplication",
"identifier": "terra",
"name": "terra",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=terra"
},
"14": {
"@type": "SoftwareApplication",
"identifier": "tidyr",
"name": "tidyr",
"provider": {
"@id": "https://cran.r-project.org",
"@type": "Organization",
"name": "Comprehensive R Archive Network (CRAN)",
"url": "https://cran.r-project.org"
},
"sameAs": "https://CRAN.R-project.org/package=tidyr"
},
"15": {
"@type": "SoftwareApplication",
"identifier": "R",
"name": "R",
"version": ">= 4.3.0"
},
"SystemRequirements": null
},
"fileSize": "6032.818KB",
"citation": [
{
"@type": "ScholarlyArticle",
"datePublished": "2025",
"author": [
{
"@type": "Person",
"givenName": [
"Kristen",
"M."
],
"familyName": "Martinet"
},
{
"@type": "Person",
"givenName": "Cristian",
"familyName": "Romn-Palacios"
},
{
"@type": "Person",
"givenName": [
"Luke",
"J."
],
"familyName": "Harmon"
}
],
"name": "SSARP: An R Package for Easily Creating Species- and Speciation- Area Relationships Using Web Databases",
"identifier": "https://doi.org/10.1101/2024.12.31.630948",
"url": "https://www.biorxiv.org/content/10.1101/2024.12.31.630948v1",
"@id": "https://doi.org/10.1101/2024.12.31.630948",
"sameAs": "https://doi.org/10.1101/2024.12.31.630948",
"isPartOf": {
"@type": "PublicationIssue",
"datePublished": "2025",
"isPartOf": {
"@type": [
"PublicationVolume",
"Periodical"
],
"name": "bioRxiv"
}
}
}
],
"releaseNotes": "https://github.com/ropensci/ssarp/blob/main/NEWS.md",
"readme": "https://github.com/ropensci/ssarp/blob/main/README.md",
"contIntegration": [
"https://codecov.io/gh/ropensci/ssarp?branch=main",
"https://github.com/ropensci/ssarp/actions/workflows/R-CMD-check.yaml"
],
"developmentStatus": "https://www.repostatus.org/#active",
"review": {
"@type": "Review",
"url": "https://github.com/ropensci/software-review/issues/685",
"provider": "https://ropensci.org"
}
}
GitHub Events
Total
- Issues event: 1
- Issue comment event: 7
- Push event: 16
Last Year
- Issues event: 1
- Issue comment event: 7
- Push event: 16
Issues and Pull Requests
Last synced: 6 months ago
All Time
- Total issues: 2
- Total pull requests: 8
- Average time to close issues: less than a minute
- Average time to close pull requests: less than a minute
- Total issue authors: 2
- Total pull request authors: 1
- Average comments per issue: 0.0
- Average comments per pull request: 0.0
- Merged pull requests: 8
- Bot issues: 1
- Bot pull requests: 0
Past Year
- Issues: 2
- Pull requests: 8
- Average time to close issues: less than a minute
- Average time to close pull requests: less than a minute
- Issue authors: 2
- Pull request authors: 1
- Average comments per issue: 0.0
- Average comments per pull request: 0.0
- Merged pull requests: 8
- Bot issues: 1
- Bot pull requests: 0
Top Authors
Issue Authors
- github-actions[bot] (1)
Pull Request Authors
- kmartinet (9)