Ecological Stoichiometry Cooperative
Return to the STOICH Database Home
 Examples
 ExamplesThis page contains several examples of how to use the STOICH-utilites to create plots or find information.
The STOICH-utilities was developed using the Tidyverse. If you need additional resources for using the Tidyverse please check out the cheatsheets.
If you don't have the STOICH-utilities installed please visit Getting Started With STOICH-utilties.
# Three options for creating a variable to store the path to the STOICH data.
# Building the path starting at your Documents directory.
myPath <- file.path(path.expand("~"), "data", "STOICH_Beta_Release_2023-07-21")
# Or with a text string.
myPath <- "C:/Users/chad/Documents/data/STOICH_Beta_Release_2023-07-21"
# Or if you set the working directory to point to the data.
myPath <- getwd()
# Load the STOICH data (using a predefined path variable)
stoichData <- stoichUtilities::loadSTOICH(dataPath=myPath)Description: Exploring the data with DataExplorer and summarytools.
# Load required packages.
library(tidyverse)
library(summarytools)
library(DataExplorer)
library(stoichUtilities)
myPath <- "C:\..." # Update this with your path to the data
#Load the data and join the tables into one wide table.
stoichData <- stoichUtilities::loadSTOICH(dataPath=myPath) |>
  stoichUtilities::joinSTOICH()
# Create a summary of the STOICH data table using summarytools formated for easy viewing.
view(summarytools::dfSummary(stoichTable))
# Create a report of the STOICH data table using DataExplorer.
DataExplorer::create_report(stoichTable)Description: Plotting latitude/elevation vs CN ratio for specific organisms.
# Load required packages.
library(tidyverse)
library(stoichUtilities)
myPath <- "C:\..." # Update this with your path to the data
#Load the data.
stoichData <- stoichUtilities::loadSTOICH(dataPath=myPath) |>
  # Filter the variables we are interested in to remove any rows that don't have values.
  stoichUtilities::filterSTOICH(var="Elevation", val=NA, condition="not equal") |>
  stoichUtilities::filterSTOICH(var="Latitude", val=NA, condition="not equal") |>
  stoichUtilities::filterSTOICH(var="CarbonToNitrogenRatio", val=NA, condition="not equal") |>
  # Filter to select only rows where the Organism Type is "Seston".
  stoichUtilities::filterSTOICH(var="Type.OrganismStoichiometry", val="Seston", condition="equal") |>
  # Join all the tables into one large wide table.
  stoichUtilities::joinSTOICH() |>
  # Select only the columns we are interested in plotting.
  select(c("Elevation.Site", "Latitude.Site", "CarbonToNitrogenRatio.OrganismStoichiometry")) |>
  # Remove any text with 4 characters or more after a "." at the end ("$") of a string.
  rename_with(~stringr::str_remove(.x, "\\.[a-zA-Z]{4,}$"))
# Plot the elevation versus CN ratio as a line.
ggplot(stoichData, aes(x=Elevation, y=CarbonToNitrogenRatio)) +
  geom_line()
# If you want to look at a plot with average CN for elevation bins, you could use the summarize function after rounding the elevation data.
smoothData <- stoichData |>
  mutate(Elevation_Smooth = 100*round(Elevation/100)) |>
  group_by(Elevation_Smooth) |>
  summarize(mean_CN_ratio = mean(CarbonToNitrogenRatio))
# Plot the averaged data.
ggplot(smoothData, aes(x=Elevation_Smooth, y=mean_CN_ratio)) +
  geom_line()Description: Mapping example with pins for different organism samples color coded.
# Load required packages.
library(tidyverse)
library(stoichUtilities)
library(sf)
library(leaflet)
myPath <- "C:\..." # Update this with your path to the data
#Load the data.
stoichData <- stoichUtilities::loadSTOICH(dataPath=myPath) |>
  # Remove any locations without GPS data
  stoichUtilities::filterSTOICH(var="Longitude", val=NA, condition="not equal") |>
  stoichUtilities::filterSTOICH(var="Latitude", val=NA, condition="not equal") |>
  # Filter to select three orders of Bryophytes.
  stoichUtilities::filterSTOICH(var="TaxonomicOrder", val=c("Hypnales", "Marchantiales", "Polygonales"), condition="equal") |>
  # Join all the tables into one large wide table.
  stoichUtilities::joinSTOICH()
# Pull out just the data we are interested in GPS & taxonomy.
gpsGroups <- stoichData |>
  # Shorten the variable names we are intersted in for convenience.
  rename(Latitude=Latitude.Site, Longitude=Longitude.Site, TaxonomicOrder=TaxonomicOrder.OrganismStoichiometry) |>
  # Select the columns we are interested in.
  select(c("Latitude", "Longitude", "TaxonomicOrder"))
# Initiate the leaflet plot.
myPlot <- leaflet() |>
  # Select the background map style.
  addProviderTiles(providers$OpenTopoMap)
# Create colored markers (one for each order selected).
blueIcon <- awesomeIcons(icon = 'ios-close', iconColor = 'black', library = 'ion', markerColor = "blue")
greenIcon <- awesomeIcons(icon = 'ios-close', iconColor = 'black', library = 'ion', markerColor = "green")
orangeIcon <- awesomeIcons(icon = 'ios-close', iconColor = 'black', library = 'ion', markerColor = "orange")
# Add markers to the plot.
myPlot <- myPlot |>
  # Select (filter) only one order from the data.frame or table for each marker color.
  addAwesomeMarkers(data = data.frame(gpsGroups %>% filter(TaxonomicOrder == "Hypnales")), lng = ~Longitude, lat = ~Latitude, icon=blueIcon) |>
  addAwesomeMarkers(data = data.frame(gpsGroups %>% filter(TaxonomicOrder == "Marchantiales")), lng = ~Longitude, lat = ~Latitude, icon=greenIcon) |>
  addAwesomeMarkers(data = data.frame(gpsGroups %>% filter(TaxonomicOrder == "Polygonales")), lng = ~Longitude, lat = ~Latitude, icon=orangeIcon)
# Display the plot.
myPlotDescription: Example of mapping seston samples with points shaded according to C:N ratio and animated to group points by year.
# Load required packages.
library(tidyverse)
library(lubridate)
library(maps)
library(gganimate)
library(stoichUtilities)
myPath <- "C:\..." # Update this with your path to the data
# Load the data
Seston <- stoichUtilities::loadSTOICH(dataPath=myPath) |>
  stoichUtilities::filterSTOICH(var="Type.OrganismStoichiometry", val="Seston", condition="equal") |> 
  stoichUtilities::joinSTOICH()
# Load the state borders
state_info <- map_data("state")
# Map the state borders
base_map <- ggplot(data = state_info, mapping = aes(x=long, y=lat, group=group)) +
  geom_polygon(color = "black", fill = "white") + 
  coord_quickmap() +
  theme_void()
# Add the Seston data to the map of state borders and set the color using the C:N ratio.
map_with_data <- base_map +
  geom_point(data = Seston, aes(x = Longitude.Site, y = Latitude.Site, color=CarbonToNitrogenRatio.OrganismStoichiometry, group=SampleYear.SampleEvent)) + 
  labs(color="C:N")
# Add animation using the year the sample was taken
map_with_animation <- map_with_data +
  transition_time(SampleYear.SampleEvent) +
  ggtitle('Year: {frame_time}',
          subtitle = 'Frame {frame} of {nframes}')
# Calculate the number of years there was sample data to determine the number of frames for the animation.
num_years <- max(Seston$SampleYear.SampleEvent) - min(Seston$SampleYear.SampleEvent) + 1
# Create the animation.
animate(map_with_animation, nframes = num_years)Description: Filter/find all samples from a salt marsh.
# Load required packages.
library(tidyverse)
library(stoichUtilities)
myPath <- "C:\..." # Update this with your path to the data
#Load the data.
stoichData <- stoichUtilities::loadSTOICH(dataPath=myPath) |>
  # Filter to select only rows where the EcosystemType is "Salt Marsh".
  stoichUtilities::filterSTOICH(var="EcosystemType", val="Salt Marsh", condition="equal") |>
  # Join all the tables into one large wide table.
  stoichUtilities::joinSTOICH() |>
  View()Description: Summarize the number of sites for each source.
# Load required packages.
library(tidyverse)
library(stoichUtilities)
myPath <- "C:\..." # Update this with your path to the data
#Load the data.
stoichData <- stoichUtilities::loadSTOICH(dataPath=myPath) |>
  # Join all the tables into one large wide table.
  stoichUtilities::joinSTOICH() |>
  # Use the dplyr package from the tidyverse to select the columns we are interested in. 
  dplyr::select(c("Title.Source", "FirstAuthor.Source", "YearPublished.Source", "Journal.Source", "LitSurveyId.Source", "Organization.Source", "Id.Site")) |>
  # Shorten column names because I don't want to keep typing ".Source".
  dplyr::rename_all(~stringr::str_remove(.x, "\\.Source")) |>
  # There are probably multiple samples/site so only keep unique entries of sites and sources.
  unique() |>
  # Group the data by Source columns.
  dplyr::group_by(Title, FirstAuthor, YearPublished, Journal, LitSurveyId, Organization) |>
  # Count the number of sites for each group.
  dplyr::summarise(Number_of_Sites = n(), .groups="keep") |>
  View()Description: Search for the furthest East (minimum longitude) sample site.
# Load required packages.
library(tidyverse)
library(stoichUtilities)
myPath <- "C:\..." # Update this with your path to the data
#Load the data and select just the Site table.
stoichData <- stoichUtilities::loadSTOICH(dataPath=myPath)[["tbl_Site"]]
# Find the row with the minimum Longitude value (drop rows with NA values).
stoichData |> 
  filter(Longitude == min(stoichData[["Longitude"]], na.rm=TRUE))# Load required packages.
library(tidyverse)
library(stoichUtilities)
myPath <- "C:\..." # Update this with your path to the data
#Load the data.
stoichData <- stoichUtilities::loadSTOICH(dataPath=myPath) |>
  # Filter out any rows without Longitude data.
  stoichUtilities::filterSTOICH(var="Longitude", val=NA, condition="not equal") |>
  # Join all the tables into one large wide table.
  stoichUtilities::joinSTOICH() |>
  # Select just the columns from the Site table.
  select(ends_with(".Site"))
# Find the row with the minimum Longitude value
stoichData |> 
  filter(Longitude.Site == min(stoichData[["Longitude.Site"]])) |> 
  # There will probably be duplicates, so keep only unique values.
  unique()Description: How many samples were taken North of 45 degrees latitude in the month of December and what was the average elevation for those samples.
# Load required packages.
library(tidyverse)
library(stoichUtilities)
myPath <- "C:\..." # Update this with your path to the data
#Load the data and select just the Site table.
stoichData <- stoichUtilities::loadSTOICH(dataPath=myPath) |>
  # Filter just December (month 12) data.
  stoichUtilities::filterSTOICH(var="SampleMonth", val=as.integer(12), condition="equal") |>
  # Filter just samples north of 45 degrees latitude.
  stoichUtilities::filterSTOICH(var="Latitude", val=45, condition="greater than") |>
  # Join all the tables into one large wide table.
  stoichUtilities::joinSTOICH()
# Count the number of rows.
nrow(stoichData)
# Calculate the mean elevation for the samples.
mean(stoichData[["Elevation.Site"]])Description: Search for the sample with the lowest Carbon 13 content in Texas.
# Load required packages.
library(tidyverse)
library(stoichUtilities)
myPath <- "C:\..." # Update this with your path to the data
# Load the data and pipe it ("|>" and "%>%" can pass a table into the next function) for further processing
stoichData <- stoichUtilities::loadSTOICH(dataPath=myPath) |>
  # Filter the STOICH data for any samples in Texas with Isotope13C content and remove any samples with unknown species.
  stoichUtilities::filterSTOICH(var="State", val="Texas", condition="Equal") |>
  stoichUtilities::filterSTOICH(var="Isotope13C", val=NA, condition="not equal") |>
  stoichUtilities::filterSTOICH(var="TaxonomicSpecies", val=NA, condition="not equal") |>
  # Join all the tables into one large wide table
  stoichUtilities::joinSTOICH() |>
  # Use the dplyr package from the tidyverse to select the columns we are interested in.
  dplyr::select(c("TaxonomicKingdom.OrganismStoichiometry",
                  "TaxonomicOrder.OrganismStoichiometry",
                  "TaxonomicFamily.OrganismStoichiometry",
                  "TaxonomicGenus.OrganismStoichiometry",
                  "TaxonomicSpecies.OrganismStoichiometry",
                  "Isotope13C.OrganismStoichiometry"))
# Find the row with the minimum Isotope13C value
stoichData |> filter(Isotope13C.OrganismStoichiometry == min(stoichData[["Isotope13C.OrganismStoichiometry"]]))Description: Search for the organism with the highest average N15 Isotope content in California.
# Load required packages.
library(tidyverse)
library(stoichUtilities)
myPath <- "C:\..." # Update this with your path to the data
# Load the data and pipe it ("|>" and "%>%" can pass a table into the next function) for further processing
stoichData <- stoichUtilities::loadSTOICH(dataPath=myPath) |>
  # Filter the STOICH data for any samples in California with Isotope15N content and remove any samples with unknown species.
  stoichUtilities::filterSTOICH(var="State", val="California", condition="Equal") |>
  stoichUtilities::filterSTOICH(var="Isotope15N", val=NA, condition="not equal") |>
  stoichUtilities::filterSTOICH(var="TaxonomicSpecies", val=NA, condition="not equal") |>
  # Join all the tables into one large wide table
  stoichUtilities::joinSTOICH() |>
  # Use the dplyr package from the tidyverse to select the columns we are interested in.
  dplyr::select(c("TaxonomicKingdom.OrganismStoichiometry",
                  "TaxonomicOrder.OrganismStoichiometry",
                  "TaxonomicFamily.OrganismStoichiometry",
                  "TaxonomicGenus.OrganismStoichiometry",
                  "TaxonomicSpecies.OrganismStoichiometry",
                  "Isotope15N.OrganismStoichiometry")) |>
  # Shorten column names because I don't want to keep typing ".OrganismStoichiometry".
  dplyr::rename_all(~stringr::str_remove(.x, "\\.OrganismStoichiometry")) |>
  # Group the data by Taxonomy.
  dplyr::group_by(TaxonomicKingdom, TaxonomicOrder, TaxonomicFamily, TaxonomicGenus, TaxonomicSpecies) |>
  # Average the N15 Isotope data for each group.
  dplyr::summarise(mean_Isotope15N = mean(Isotope15N), .groups="keep")
# Find the row with the maximum average Isotope15N value
stoichData |> filter(mean_Isotope15N == max(stoichData[["mean_Isotope15N"]]))