### QUBES iNaturalist R Data Tutorial - Biodiversity for Sustainable Futures ### ### Downloading and Visualizing Project Data from the iNaturalist Database ### #### 1. Download a dataset from iNaturalist to explore a species of interest or use the dataset included in this example. #### #### 2. Loading your dataset into R #### rm(list = ls(all = TRUE)) # clear global environment getwd() # This will tell you where your working directory is currently set to # If your current wd location is different than what you want, replace the wd location by using setwd() setwd("/Users/justinedoll/Desktop/iNatR_Tutorial_Data/") #replace with your wd location dir() # You can also check to see all the files in that specific location Bombus_nosehill <- read.csv("bombus_nosehill_2023.csv") #replace with your file name str(Bombus_nosehill) # You can check the structure of your data to see what type of data is contained within each column colnames(Bombus_nosehill) # You can also check the column names to see all the columns in your data and to ensure that the data uploaded correctly. Normally, data from iNaturalist will upload nicely but it is always good to check. colnames(Bombus_nosehill)[colnames(Bombus_nosehill) == "scientific_name"] <- "insect_name" colnames(Bombus_nosehill)[colnames(Bombus_nosehill) == "field.interaction..visited.flower.of"] <- "visited_flower" head(Bombus_nosehill $insect_name) # Using "head" gives you the first few values of data head(Bombus_nosehill $visited_flower) #### 3.1. Exploring insect and plant species in your dataset #### # To install any packages that you do not have just delete the pound sign in front of the code and run it #install.packages("tidyverse") library(tidyverse) # We are going to create a simplified object with just plant and pollinator data plants_and_pollinators <- Bombus_nosehill %>% filter(!is.na(insect_name), !is.na(visited_flower)) # Remove any NA values and filter the data by your columns of interest. Store this in a new object. plants_and_pollinators <- plants_and_pollinators %>% select(insect_name,visited_flower) # Selects just your columns of interest and stores it in the plants_and_pollinators object plants_and_pollinators$insect_name plants_and_pollinators$visited_flower # Print a list of all the insect and plant names in your dataset n_distinct(plants_and_pollinators$insect_name) n_distinct(plants_and_pollinators$visited_flower) # Number of different insect and plant species included in your dataset unique(plants_and_pollinators$insect_name) unique(plants_and_pollinators$visited_flower) # Unique names of all the insects and plants in your dataset #### 3.2. Exploring plant-pollinator interactions ##### Interactions <- plants_and_pollinators %>% group_by(insect_name,visited_flower) %>% summarise(n = n()) # Summarizes the number of times each insect visited each type of flower in the plants_and_pollinators data frame. We will use the "Interactions" object again in part 4 print(Interactions) # Print a table with the interactions between insect and plant species with a count of how many times that interaction occurs ## Finding the most visited plants ## unique_insect_count <- Interactions %>% group_by(visited_flower) %>% summarise(unique_insect_count = n_distinct(insect_name)) # Calculate the unique_insect_count for each unique "visited_flower" sorted_flowers <- unique_insect_count %>% arrange(desc(unique_insect_count)) # Sort the data in descending order by unique_insect_count # Create a bar plot most_visited_plants <- ggplot(sorted_flowers, aes(x = reorder(visited_flower, unique_insect_count), y = unique_insect_count)) + geom_bar(stat = "identity", fill = "skyblue") + coord_flip() + # Flip the coordinates for horizontal bars labs(x = "Plant Name", y = "Unique Insects Observed") + theme_minimal() # Use a minimal theme print(most_visited_plants) ### Finding the insects that visit the most plant species ### unique_visited_flower_count <- Interactions %>% summarise(unique_visited_flower_count = n_distinct(visited_flower)) # Calculate the unique_visited_flower_count for each unique "insect_name" sorted_insects <- unique_visited_flower_count %>% arrange(desc(unique_visited_flower_count)) # Sort the data in descending order by unique_visited_flower_count # Create a bar plot generalist_pollinators <- ggplot(sorted_insects, aes(x = reorder(insect_name, unique_visited_flower_count), y = unique_visited_flower_count)) + geom_bar(stat = "identity", fill = "skyblue") + coord_flip() + # Flip the coordinates for horizontal bars labs(x = "Insect Name", y = "Unique Visited Flower Count") + theme_minimal() # Use a minimal theme print(generalist_pollinators) #### 3.3. Graphing observations through time #### seasonality <- Bombus_nosehill #create a new object seasonality$observed_on <- as.Date(seasonality$observed_on) # Convert observed_on to Date format seasonality$month <- format(seasonality$observed_on, "%Y-%m") # Extract month from observed date obs_count_month <- seasonality %>% # Count observations by month group_by(month) %>% summarise(count = n()) ggplot(obs_count_month, aes(x = month, y = count)) + # Create plot geom_line() + geom_point() + labs(x = "Month", y = "Number of Observations", title = "Number of Observations by Month") #### 3.4. Mapping observations in space #### # Create an interactive map to see where observations have been made # install.packages("leaflet") # delete pound sign to install package library(leaflet) data_filtered <- Bombus_nosehill %>% filter(!is.na(latitude) & !is.na(longitude)) # Filter out observations with missing coordinates map <- leaflet(data = data_filtered) %>% addTiles() %>% addMarkers(~longitude, ~latitude, popup = ~place_guess) # Create a leaflet map map # Display the map #### 4.1. Heat Map Visualization #### # Select your target data to create a species-by-plant matrix subdata <- data.frame(Insect_species= Bombus_nosehill$insect_name, Plant_species= Bombus_nosehill$visited_flower) mat <- xtabs(~Insect_species+Plant_species, subdata) # Turn your subdata into a matrix heatmap(mat, Rowv=NA, Colv=NA, main="Insect-Plant Associations") # Create a heat map #### 4.2. Bipartite Analysis #### # To install any packages that you do not have just delete the pound sign in front of the code and run it #install.packages("bipartite") # Load the package library(bipartite) plants_and_pollinators <- Bombus_nosehill %>% filter(!is.na(insect_name), !is.na(visited_flower)) # Filter the data by your columns of interest. Store this in a new object, I have named mine "plants_and_pollinators." # Remove any NA values so you hopefully won’t run into problems down the road plants_and_pollinators <- plants_and_pollinators %>% select(insect_name,visited_flower) # Selects just your columns of interest and stores it in the plants_and_pollinators object Interactions<- plants_and_pollinators %>% group_by(insect_name,visited_flower) %>% summarise(n = n()) # This code summarizes the number of times each insect visited each type of flower in the plants_and_pollinators data frame. # Reshape the data using pivot_wider() function interactmatrix <- Interactions %>% pivot_wider(names_from = insect_name, values_from = n, values_fill = 0) # Convert the "visited_flower" column to row names using column_to_rownames() function interactmatrix <- column_to_rownames(interactmatrix, var = "visited_flower") plotweb(interactmatrix) #create your plot web #### 4.3 Additional analysis with Bipartite #### species_analysis<- specieslevel(interactmatrix) #can get metrics for each of the species head(species_analysis) network_analysis <- networklevel(interactmatrix) #can get metrics for the whole network head(network_analysis) ?bipartite #will tell you more about the bipartite package and it's functions #### 4.4. Data Visualization with bipartiteD3 #### #install.packages("bipartiteD3", dependencies = TRUE) # remove hashtag and run code to install package and dependencies library(bipartiteD3) # load package pretty_network <- Interactions # use Interactions matrix from earlier pretty_network %>% # Select data, then bipartite_D3(. , # Opens a webpage with your bipartiteD3 network SiteNames = "Plant-Pollinator Interactions", # Creates your main title PrimaryLab = "Pollinators", # Creates left-hand title SecondaryLab = "Plants") #### 4.5. Species specific filter bipartiteD3 network code #### ### If your dataset contains many different plant and insect species interactions, you can create a bipartite matrix for the whole network or you can filter the dataset to create a visualization for a species of interest. # Let’s say within the larger dataset I am interested in seeing how many different plants were visited by Red Belted Bumble Bees, (Bombus rufocinctus). d3Brufocinctus <- Interactions %>% filter(grepl("Bombus rufocinctus",insect_name)) # filter for Bombus rufocinctus bipartite_D3(d3Brufocinctus, SiteNames = "Bombus rufocinctus Interactions", # Main title PrimaryLab = "Bombus rufocinctus", # Creates left-hand title SecondaryLab = "Plants") # Creates right-hand title # You could also do this for any plant species you are interested. Let’s see how many different pollinators prairie crocus (Pulsatilla nuttalliana) supports. d3Pnuttalliana <- Interactions %>% filter(grepl("Pulsatilla nuttalliana",visited_flower)) # filter for Pulsatilla nuttalliana bipartite_D3(d3Pnuttalliana, SiteNames = " Pulsatilla nuttalliana Interactions", # Main title PrimaryLab = "Pollinators", # Creates left-hand title SecondaryLab = "Pulsatilla nuttalliana") # Creates right-hand title