# Check which species have habitat associationsmatched_species <- final_data %>%filter(!is.na(Habitat)) %>%# Keep only species with habitat datadistinct(scientific_name) %>%nrow()# See which species don't have habitat associationsunmatched_species <- iNat_obs %>%anti_join(species_with_community, by ="scientific_name")# Create a summaryprint(paste("Total species in iNat_obs:", n_distinct(iNat_obs$scientific_name)))
[1] "Total species in iNat_obs: 526"
Code
print(paste("Species with habitat associations:", matched_species))
[1] "Species with habitat associations: 12"
Code
print(paste("Species without habitat associations:", nrow(unmatched_species)))
[1] "Species without habitat associations: 1224"
Code
library(ggplot2)# 2. Count of observations by Communityggplot(final_data, aes(y = Community)) +geom_bar() +theme_minimal() +labs(title ="Number of Observations per Community",x ="Count",y ="Community")
Code
# 3. Create a summary of multiple community associationscommunity_combinations <- final_data_grouped %>%mutate(community_count = stringr::str_count(Communities, ";") +1) %>%ggplot(aes(x = community_count)) +geom_histogram(binwidth =1) +theme_minimal() +labs(title ="Number of Communities per Observation",x ="Number of Associated Communities",y ="Count")# 4. Interactive map using leafletlibrary(leaflet)
Warning: package 'leaflet' was built under R version 4.4.3
Code
# Create a color palette for communitiescommunities <-unique(final_data$Community)pal <-colorFactor(palette ="Set3", domain = communities)
Code
leaflet(final_data) %>%addControl(html ='<div style=" position: absolute; left: 50%; transform: translateX(-50%); background-color: rgba(255,255,255,0.8); padding: 10px; border-radius: 5px; box-shadow: 0 0 15px rgba(0,0,0,0.2); margin-left: 100px; /* Shift right by adjusting this value */ margin-top: -80px; /* Shift up by adjusting this value */ "><h3 style="margin: 0; text-align: center;">Wisconsin Species Community Associations from iNaturalist Observations</h3></div>',position ="topleft" ) %>%# Add different base map optionsaddProviderTiles(providers$OpenStreetMap, group ="OpenStreetMap") %>%addProviderTiles(providers$CartoDB.Positron, group ="Carto") %>%addProviderTiles(providers$Esri.WorldImagery, group ="Satellite") %>%# Add clustered points with image popupsaddCircleMarkers(~longitude, ~latitude,color =~pal(Community),radius =3,opacity =0.8,popup =~paste("<div style='width:200px'>", # Container with fixed width"<img src='", image_url, "' style='width:100%; margin:auto; display:block'>", # Image"<br>","<b>Species:</b>", scientific_name,"<br><b>Community:</b>", Community,"<br><b>Habitat:</b>", Habitat,"</div>" ),clusterOptions =markerClusterOptions() ) %>%# Add legend and layers controladdLegend("bottomright", pal = pal, values = communities,title ="Community Types",opacity =0.7) %>%addLayersControl(baseGroups =c("OpenStreetMap", "Satellite", "Carto"),options =layersControlOptions(collapsed =FALSE) )
Code
# Create network of communities that share speciescommunity_network <- final_data %>%select(scientific_name, Community) %>%distinct() %>%group_by(scientific_name) %>%filter(n() >1) %>%ungroup()# Create edges between communitiesedges <- community_network %>%group_by(scientific_name) %>%summarize(communities =list(Community)) %>%mutate(community_pairs =map(communities, combn, m =2, simplify =FALSE)) %>%unnest(community_pairs) %>%count(from =map_chr(community_pairs, 1), to =map_chr(community_pairs, 2))# Create graph and calculate degreegraph <-graph_from_data_frame(edges)V(graph)$degree <-degree(graph)# Create and plot network with enhanced stylingggraph(graph, layout ="fr") +# Add edges (connections)geom_edge_link(aes(width = n, alpha = n), color ="gray50") +# Add nodes (points)geom_node_point(aes(color = name, size = degree)) +# Add labelsgeom_node_text(aes(label = name), repel =TRUE, size =4,fontface ="bold") +# Customize colors and stylingscale_color_viridis_d() +scale_edge_width(range =c(0.5, 3)) +scale_edge_alpha(range =c(0.2, 0.8)) +scale_size(range =c(5, 15)) +# Customize themetheme_void() +theme(plot.title =element_text(size =16, face ="bold", hjust =0.5),legend.position ="right" ) +# Add titles and labelslabs(title ="Community Connections through Shared Species",edge_width ="Number of shared species",color ="Community",size ="Number of connections")
Source Code
---title: "Merge_data"format: htmlhtml:self-contained: truetoc: truetoc-title: "Navigation"toc-depth: 2code-fold: Truecode-tools: trueeditor: visual---```{r, warning=FALSE, include=FALSE}# First, let's load the required librarieslibrary(dplyr)library(readr)library(readxl)library(stringr)library(tidyr)iNat_obs <- read_csv("iNat_obs.csv")WWAP_Associations <- read_csv("WWAP_Associations.csv")WWAP_Community <- read_csv("WWAP_Communities.csv")``````{r, warning=FALSE, include=FALSE}# First, let's rename the tables for clarityhabitat_lookup <- WWAP_Community # your community-habitat lookup tablespecies_associations <- WWAP_Associations # your species-habitat associations# Convert species associations to long format first (if not already done)species_long <- species_associations %>% pivot_longer( cols = -c(Group, Species), # keep these columns names_to = "Habitat", values_to = "Association" ) %>% filter(!is.na(Association)) # remove NA associations# Now perform the left join to add community classificationsspecies_with_community <- species_long %>% left_join(habitat_lookup, by = c("Habitat" = "Habitat")) %>% select(Group, Species, Habitat, Community, Association)# Check the resulthead(species_with_community)``````{r, warning=FALSE, include=FALSE}# Clean up the species names in species_with_communityspecies_with_community <- species_with_community %>% mutate( # Extract just the scientific name from the parenthetical format scientific_name = str_extract(Species, "^[^(]+"), # Gets everything before the ( # Or if you need to extract from inside parentheses: # scientific_name = str_extract(Species, "(?<=\$$).*?(?=\$$)"), scientific_name = trimws(scientific_name) # Remove any extra whitespace )``````{r, warning=FALSE, include=FALSE}final_data <- iNat_obs %>% left_join(species_with_community, by = "scientific_name")``````{r, warning=FALSE, include=FALSE}# Option 1: Keep all combinations (if you want to see all habitat associations for each observation)final_data <- iNat_obs %>% left_join(species_with_community, by = "scientific_name", relationship = "many-to-many")# Option 2: Group habitat information before joiningspecies_with_community_grouped <- species_with_community %>% group_by(scientific_name) %>% summarise( Habitats = paste(unique(Habitat), collapse = "; "), Communities = paste(unique(Community), collapse = "; ") )final_data_grouped <- iNat_obs %>% left_join(species_with_community_grouped, by = "scientific_name")``````{r}# Check which species have habitat associationsmatched_species <- final_data %>%filter(!is.na(Habitat)) %>%# Keep only species with habitat datadistinct(scientific_name) %>%nrow()# See which species don't have habitat associationsunmatched_species <- iNat_obs %>%anti_join(species_with_community, by ="scientific_name")# Create a summaryprint(paste("Total species in iNat_obs:", n_distinct(iNat_obs$scientific_name)))print(paste("Species with habitat associations:", matched_species))print(paste("Species without habitat associations:", nrow(unmatched_species)))``````{r}library(ggplot2)# 2. Count of observations by Communityggplot(final_data, aes(y = Community)) +geom_bar() +theme_minimal() +labs(title ="Number of Observations per Community",x ="Count",y ="Community")``````{r}# 3. Create a summary of multiple community associationscommunity_combinations <- final_data_grouped %>%mutate(community_count = stringr::str_count(Communities, ";") +1) %>%ggplot(aes(x = community_count)) +geom_histogram(binwidth =1) +theme_minimal() +labs(title ="Number of Communities per Observation",x ="Number of Associated Communities",y ="Count")# 4. Interactive map using leafletlibrary(leaflet)# Create a color palette for communitiescommunities <-unique(final_data$Community)pal <-colorFactor(palette ="Set3", domain = communities)``````{r}leaflet(final_data) %>%addControl(html ='<div style=" position: absolute; left: 50%; transform: translateX(-50%); background-color: rgba(255,255,255,0.8); padding: 10px; border-radius: 5px; box-shadow: 0 0 15px rgba(0,0,0,0.2); margin-left: 100px; /* Shift right by adjusting this value */ margin-top: -80px; /* Shift up by adjusting this value */ "><h3 style="margin: 0; text-align: center;">Wisconsin Species Community Associations from iNaturalist Observations</h3></div>',position ="topleft" ) %>%# Add different base map optionsaddProviderTiles(providers$OpenStreetMap, group ="OpenStreetMap") %>%addProviderTiles(providers$CartoDB.Positron, group ="Carto") %>%addProviderTiles(providers$Esri.WorldImagery, group ="Satellite") %>%# Add clustered points with image popupsaddCircleMarkers(~longitude, ~latitude,color =~pal(Community),radius =3,opacity =0.8,popup =~paste("<div style='width:200px'>", # Container with fixed width"<img src='", image_url, "' style='width:100%; margin:auto; display:block'>", # Image"<br>","<b>Species:</b>", scientific_name,"<br><b>Community:</b>", Community,"<br><b>Habitat:</b>", Habitat,"</div>" ),clusterOptions =markerClusterOptions() ) %>%# Add legend and layers controladdLegend("bottomright", pal = pal, values = communities,title ="Community Types",opacity =0.7) %>%addLayersControl(baseGroups =c("OpenStreetMap", "Satellite", "Carto"),options =layersControlOptions(collapsed =FALSE) )``````{r, warning=FALSE, include=FALSE, echo=FALSE}library(ggraph)library(igraph)library(purrr)library(viridis)# Seasonal patternsif("date" %in% colnames(final_data)) { final_data %>% mutate(month = lubridate::month(date)) %>% ggplot(aes(x = month, fill = Community)) + geom_bar(position = "stack") + scale_x_continuous(breaks = 1:12) + theme_minimal() + labs(title = "Species Observations by Month and Community", x = "Month", y = "Count")}``````{r, warning=FALSE}# Create network of communities that share speciescommunity_network <- final_data %>% select(scientific_name, Community) %>% distinct() %>% group_by(scientific_name) %>% filter(n() > 1) %>% ungroup()# Create edges between communitiesedges <- community_network %>% group_by(scientific_name) %>% summarize(communities = list(Community)) %>% mutate(community_pairs = map(communities, combn, m = 2, simplify = FALSE)) %>% unnest(community_pairs) %>% count(from = map_chr(community_pairs, 1), to = map_chr(community_pairs, 2))# Create graph and calculate degreegraph <- graph_from_data_frame(edges)V(graph)$degree <- degree(graph)# Create and plot network with enhanced stylingggraph(graph, layout = "fr") + # Add edges (connections) geom_edge_link(aes(width = n, alpha = n), color = "gray50") + # Add nodes (points) geom_node_point(aes(color = name, size = degree)) + # Add labels geom_node_text(aes(label = name), repel = TRUE, size = 4, fontface = "bold") + # Customize colors and styling scale_color_viridis_d() + scale_edge_width(range = c(0.5, 3)) + scale_edge_alpha(range = c(0.2, 0.8)) + scale_size(range = c(5, 15)) + # Customize theme theme_void() + theme( plot.title = element_text(size = 16, face = "bold", hjust = 0.5), legend.position = "right" ) + # Add titles and labels labs(title = "Community Connections through Shared Species", edge_width = "Number of shared species", color = "Community", size = "Number of connections")```