In this project, I analyze pest sightings in the City of Seattle for the year 2023 using network analysis techniques. The data, provided by a small pest control company in Seattle where I work, includes services for various pests at different locations across the city. Because this data is proprietary, a link to the data will not be provided, but through the analysis, I will show brief segments of the data to ensure the process is clear.
The primary objective of this project is to create a bipartite graph that visualizes the relationships between pest species and neighborhoods, providing insights into pest distribution patterns throughout Seattle. Additional objectives of this project are to analyze seasonal variations in pest sightings and to develop skills in network analysis and visualization techniques. The project seeks to answer research questions such as: What are the most common pest species in Seattle? How do pest sightings vary across different neighborhoods and seasons? Can network visualization techniques effectively highlight patterns in pest distribution?
Because this is a two-mode network analysis, the nodes in the network represent two distinct types: pest species and locations. Each edge in the network represents a sighting of a pest species in a particular neighborhood. It is important to note that a sighting does not necessarily mean a pest was physically seen; rather, it indicates that pest professionals were hired to address the pest issue, whether it was seen, believed to be an issue, or part of a preventative service.
By focusing on visualization strategies for large networks, this
project leverages the bipartiteD3 package in R to create
interactive and informative visualizations. The analysis includes
grouping pests and neighborhoods into broader categories to simplify the
visualization and emphasize general trends.
Overall, this project demonstrates the application of network analysis techniques to real-world data, offering a practical perspective on pest management in the City of Seattle.
# Install necessary packages (uncomment if not already installed)
# install.packages(c("bipartiteD3", "bipartite", "readxl", "r2d3", "tidyverse", "RColorBrewer", "sf", "rnaturalearth", "rnaturalearthdata", "patchwork", "xlsx", "tidygeocoder", "lubridate", "printr"))
# loading the necessary libraries
library(bipartiteD3) # for creating interactive bipartite graphs
library(bipartite) # for analyzing bipartite graphs
library(readxl) # for reading excel files
library(r2d3) # for creating d3 visualizations
library(tidyverse) # includes dplyr, ggplot2, and other packages for data manipulation and visualization
library(RColorBrewer) # for creating custom color palettes
library(sf) # for handling spatial data
library(rnaturalearth) # for downloading natural earth map data
library(rnaturalearthdata) # companion package for rnaturalearth
library(xlsx) # for writing data to excel files
library(tidygeocoder) # for geocoding addresses to obtain latitude and longitude
library(lubridate) # for handling date and time data
library(printr) # for printing data frames in a nice format
The dataset contains pest sightings for the year 2023 in the City of Seattle. It includes information on various pest species at different locations throughout the city.
Columns seen throughout the analysis process include:
Date: Date of the sightingSeason: Season when the sighting occurredAddress: Location of the sightingTarget: Pest speciesLatitude and Longitude: Geographic
coordinates of the locationNeighborhood: Grouped neighborhoods in Seattle based on
geographic boundariesShape_area and Shape_len: Area and length
of the neighborhood shape, used to create the neighborhood
groupingsgeometry: Created by the sf package to
handle spatial dataOBJECTID: Unique identifier for each neighborhood
(provided by the shapefile data)L_HOOD: Original neighborhood names (provided by the
shapefile data)S_HOOD: Sub-neighborhood names (provided by the
shapefile data)S_HOOD_ALT: Alternative sub-neighborhood names
(provided by the shapefile data)The original data set contained over 30,000 entries, each representing a service performed throughout the year. Each entry included detailed information such as the name of the individual or business, address, materials used, payment information, specific pest species targeted, as well as other potentially identifying information. For privacy reasons, all personally identifiable information, excluding addressees, were removed.
Scope:
Nodes:
Edges:
The data is first imported from an Excel file and filtered to only include sightings from Seattle addresses.
# setting our working directory and reading the data
setwd("C:/Users/sarah/OneDrive/School/_Network Analysis & Visualization/Final_Project/Seattle Pest Data 2023")
sea_pests <- read_excel("sea_pests.xlsx")
# filtering to only include Seattle addresses
sea_pests <- sea_pests %>%
filter(grepl("Seattle", Address, ignore.case = TRUE))
# showing the number of rows after filtering (original 30,409 entries)
nrow(sea_pests)
## [1] 12113
In this step we geocode the addresses to obtain latitude and longitude coordinates for each sighting location. This will allow us to map the sightings more accurately and group them into neighborhoods.
We will use the tidygeocoder package for this task.
# creating a new variable called 'coordinates' that takes the addresses and
# uses tidygeocoder to convert them to lat/long coordinates
# (I am commenting out the below code because it takes a long time to run, and I don't
# want to run it every time I knit the document. I will uncomment it when I need to run it.)
# sea_pests$coordinates <- tidygeocoder::geo(sea_pests$Address)
# renaming the column 'coordinates$lat' to latitude and 'coordinates$long' to longitude
# and only keeping the necessary columns
sea_pests <- sea_pests %>%
# mutate(Latitude = coordinates$lat,
# Longitude = coordinates$long) %>%
select(Date, Target, Latitude, Longitude)
# show all column names to make sure the new columns were added and named correctly
colnames(sea_pests)
## [1] "Date" "Target" "Latitude" "Longitude"
In this step, we will do some of the initial work to clean and
prepare our data. This includes converting the Date column
to a date format, creating a new column for the season based on the
date, and checking for missing values.
# converting the data in our 'Date' column to Date format using the 'lubridate' package
sea_pests <- sea_pests %>%
mutate(Date = mdy(Date))
# adding a 'Season' column based on the Month
sea_pests <- sea_pests %>%
mutate(Season = case_when(
month(Date) %in% c(12, 1, 2) ~ "Winter",
month(Date) %in% c(3, 4, 5) ~ "Spring",
month(Date) %in% c(6, 7, 8) ~ "Summer",
month(Date) %in% c(9, 10, 11) ~ "Fall",
TRUE ~ NA_character_
))
# checking for any NA values in the dataframe
sum(is.na(sea_pests))
## [1] 0
# checking that our date is formatted and our season column was created
sea_pests %>% slice_head(n = 1)
| Date | Target | Latitude | Longitude | Season |
|---|---|---|---|---|
| 2023-01-02 | Rodents | 47.69742145 | -122.347594768961 | Winter |
In this section, we will group the pest species into broader categories to simplify the analysis and visualization process. This will help us focus on the general trends and patterns of pest populations in Seattle.
We will use the case_when function from the
dplyr package to create new categories based on the
original noted pest species in the data.
# the names used below to create the broader groups are based on the original pest types that are manually logged when completing a service. These are documented by technicians while they are on site and are, unfortunately, not standardized.
sea_pests <- sea_pests %>%
mutate(Target = case_when(
Target %in% c("Ants - Carpenter", "Ants - Nuisance", "Ants - Pavement",
"Ants", "Ants - Crawling Insects", "Ants - Odorous",
"Ants - Moisture", "Ants _ Ants", "Ants - General Ants") ~ "Ants",
Target %in% c("Rodents - Mice", "Rodents - Rats", "Rodents", "Vertebrate",
"Vertebrate - Large", "Vertebrate - Small", "Vertebrate - General",
"Rodents, Rodents - Mice, Rodents - Rats", "Rodents, Rodents - Mice",
"Rodents - Mice, Rodents - Rats", "Rodents - General") ~ "Rodents",
Target %in% c("Flies - House", "Flying Insects",
"Flying Insects, General insect control") ~ "Flying Insects",
Target %in% c("Biting Insects - Bed Bugs", "Biting Insects - Fleas",
"Biting Insects - Mites",
"Biting Insects, Biting Insects - Bed Bugs", "Biting Insects, Biting Insects - Fleas",
"Biting Insects - Bed Bugs, General insect control",
"Biting Insects - Fleas, General insect control",
"Biting Insects - Fleas, General insect control, Bed Bugs") ~ "Biting Insects",
Target %in% c("Stinging Insects", "Wasps", "General insect control, Stinging Insects",
"Stinging Insects, General insect control", "Hornets",
"Hornet - Stinging Insect") ~ "Stinging Insects",
Target %in% c("Fabric Pests", "Food Storage Pests", "WDO - Beetles",
"WDO - Termites", "Fabric Pests, General insect control",
"Food Storage Pests, General insect control") ~ "Storage and Structure Pests",
Target == "Cockroaches" ~ "Cockroaches",
Target == "Spiders" ~ "Spiders",
TRUE ~ Target # Do not change other entries
))
# creating a table to show the counts of each pest category
sea_pests %>%
group_by(Target) %>%
summarise(Count = n(), .groups = 'drop') %>%
arrange(desc(Count))
| Target | Count |
|---|---|
| Rodents | 5666 |
| Ants | 3783 |
| Cockroaches | 1907 |
| Biting Insects | 385 |
| Storage and Structure Pests | 93 |
| Stinging Insects | 89 |
| Spiders | 86 |
| Flying Insects | 67 |
| Misc Crawling Insects | 37 |
Below is a breakdown of the pest categories we have created based on the original pest species in the data, in a way that is easier to read:
| Category | Types |
|---|---|
| Ants | Carpenter, Nuisance, Pavement, Odorous House, Moisture, and other Misc/General Ants |
| Rodents | Mice, Rats, Misc. Vertebrates |
| Cockroaches | General, German, American, and Oriental Cockroaches |
| Biting Insects | Bed Bugs, Fleas, Mites |
| Storage and Structure Pests | Fabric Pests (moths, carpet beetles), Food Storage Pests (non wood-destroying storage beetles, weevils), Wood-Destroying Beetles, Termites |
| Stinging Insects | Wasps, Hornets |
| Spiders | General Spiders |
| Flying Insects | House, Fruit, and Drain Flies. Other Misc general non-stinging Flying Insects |
| Misc Crawling Insects | Silverfish, Stinkbugs, Other Crawling Insects |
Now, we group the pest sightings by neighborhoods using the geographic coordinates and a shapefile for neighborhood boundaries in Seattle. This process involves reading the shapefile, transforming the coordinates, and joining the pest data with the neighborhood data.
The packages we use in this section are sf for handling
spatial data, rnaturalearth for downloading the shapefile,
rnaturalearthdata for accessing the shapefile data, and
dplyr for data manipulation.
# reading in the shapefile to define neighborhood boundaries based on coordinates
neighborhoods <- sf::st_read("Neighborhood_Map_Atlas_Neighborhoods.shp")
# checking the coordinate reference systems (CRS) of both datasets
st_crs(sea_pests) # 4326
st_crs(neighborhoods) # 2926
# because the CRS of the shapefile is 2926, we need to transform it to match the pest data
neighborhoods <- st_transform(neighborhoods, crs = 4326)
# converting pest data to spatial data frame
pest_sf <- st_as_sf(sea_pests, coords = c("Longitude", "Latitude"), crs = 4326)
# joining the pest data with the neighborhood data
pest_neighborhoods <- st_join(pest_sf, neighborhoods, join = st_within)
# displaying the first few rows to verify the join
head(pest_neighborhoods)
| Date | Target | Season | geometry | OBJECTID | L_HOOD | S_HOOD | S_HOOD_ALT | Shape__Are | Shape__Len |
|---|---|---|---|---|---|---|---|---|---|
| 2023-01-02 | Rodents | Winter | POINT (-122.3476 47.69742) | 118 | Northwest | Greenwood | NA | 42044564 | 26501.53 |
| 2023-01-02 | Rodents | Winter | POINT (-122.3476 47.69742) | 118 | Northwest | Greenwood | NA | 42044564 | 26501.53 |
| 2023-01-03 | Rodents | Winter | POINT (-122.3659 47.56881) | 90 | Delridge | North Delridge | Avalon, Luna Park, Pigeon Point | 29454657 | 23549.93 |
| 2023-01-03 | Cockroaches | Winter | POINT (-122.3289 47.61368) | 100 | Capitol Hill | Broadway | Pike/Pine | 30239241 | 26851.95 |
| 2023-01-03 | Cockroaches | Winter | POINT (-122.3289 47.61368) | 100 | Capitol Hill | Broadway | Pike/Pine | 30239241 | 26851.95 |
| 2023-01-03 | Cockroaches | Winter | POINT (-122.3289 47.61368) | 100 | Capitol Hill | Broadway | Pike/Pine | 30239241 | 26851.95 |
The sub-neighborhood data and the map (Figure 1) used for this step of our analysis can be explored through the Seattle City GIS open data portal.
Figure 1: Seattle Sub-Neighborhoods Map.
Source: Seattle City GIS open data portal.
# segmenting the myriad sub-neighborhoods into 7 distinct neighborhoods
# define a mapping function for neighborhood groupings
get_custom_segment <- function(neighborhood) {
if (neighborhood %in% c("Loyal Heights", "Ballard", "Whittier Heights",
"West Woodland", "Phinney Ridge", "Wallingford",
"Fremont", "Green Lake", "Broadview", "Bitter Lake",
"Haller Lake", "North Beach/Blue Ridge", "Licton Springs",
"Crown Hill", "Greenwood", "Sunset Hill")) {
return("NW Seattle")
} else if (neighborhood %in% c("View Ridge", "Ravenna", "Sand Point", "Bryant",
"Windermere", "Laurelhurst", "Roosevelt",
"University of Washington", "Wedgwood",
"Victory Heights", "Matthews Beach", "Meadowbrook",
"Olympic Hills", "Cedar Park", "Pinehurst",
"Maple Leaf", "University District",
"University Heights")) {
return("NE Seattle")
} else if (neighborhood %in% c("East Queen Anne", "West Queen Anne",
"Lower Queen Anne", "North Queen Anne",
"Westlake", "Lawton Park", "Briarcliff",
"Southeast Magnolia", "Interbay")) {
return("Magnolia/Queen Anne")
} else if (neighborhood %in% c("Eastlake", "Madrona", "Harrison/Denny-Blaine",
"Minor", "Leschi", "Mann", "First Hill",
"Yesler Terrace", "Portage Bay", "Montlake",
"Madison Park", "Broadway", "Stevens")) {
return("Central Seattle")
} else if (neighborhood %in% c("South Lake Union", "Pike-Market", "Belltown",
"International District", "Central Business District",
"Pioneer Square", "Denny Triangle")) {
return("Downtown Seattle")
} else if (neighborhood %in% c("South Park", "Seaview", "Gatewood",
"Arbor Heights", "Alki", "North Admiral",
"Fairmount Park", "Genesee", "Fauntleroy",
"Highland Park", "North Delridge", "Riverview",
"High Point", "South Delridge", "Roxhill")) {
return("West Seattle")
} else if (neighborhood %in% c("Atlantic", "SODO", "Georgetown",
"North Beacon Hill", "Mid-Beacon Hill",
"South Beacon Hill", "Holly Park", "Brighton",
"Dunlap", "Rainier Beach", "Rainier View",
"Mount Baker", "Columbia City", "Seward Park",
"Industrial District", "Harbor Island")) {
return("South/SE Seattle")
} else {
return(NA)
}
}
# apply the mapping function to create a new column for custom neighborhoods
pest_neighborhoods <- pest_neighborhoods %>%
mutate(Neighborhood = sapply(S_HOOD, get_custom_segment))
# displaying the first few rows to verify the new column
head(pest_neighborhoods)
| Date | Target | Season | geometry | OBJECTID | L_HOOD | S_HOOD | S_HOOD_ALT | Shape__Are | Shape__Len | Neighborhood |
|---|---|---|---|---|---|---|---|---|---|---|
| 2023-01-02 | Rodents | Winter | POINT (-122.3476 47.69742) | 118 | Northwest | Greenwood | NA | 42044564 | 26501.53 | NW Seattle |
| 2023-01-02 | Rodents | Winter | POINT (-122.3476 47.69742) | 118 | Northwest | Greenwood | NA | 42044564 | 26501.53 | NW Seattle |
| 2023-01-03 | Rodents | Winter | POINT (-122.3659 47.56881) | 90 | Delridge | North Delridge | Avalon, Luna Park, Pigeon Point | 29454657 | 23549.93 | West Seattle |
| 2023-01-03 | Cockroaches | Winter | POINT (-122.3289 47.61368) | 100 | Capitol Hill | Broadway | Pike/Pine | 30239241 | 26851.95 | Central Seattle |
| 2023-01-03 | Cockroaches | Winter | POINT (-122.3289 47.61368) | 100 | Capitol Hill | Broadway | Pike/Pine | 30239241 | 26851.95 | Central Seattle |
| 2023-01-03 | Cockroaches | Winter | POINT (-122.3289 47.61368) | 100 | Capitol Hill | Broadway | Pike/Pine | 30239241 | 26851.95 | Central Seattle |
The neighborhoods in Seattle have been divided into seven distinct regions based on geographic boundaries and proximity. This division helps in simplifying the analysis and visualization of pest sightings across the city.
The following table summarizes the neighborhoods and their corresponding regions:
| Neighborhood | Sub-Neighborhoods |
|---|---|
| NW Seattle | Loyal Heights, Ballard, Whittier Heights, West Woodland, Phinney Ridge, Wallingford, Fremont, Green Lake, Broadview, Bitter Lake, Haller Lake, North Beach/Blue Ridge, Licton Springs, Crown Hill, Greenwood, Sunset Hill |
| NE Seattle | View Ridge, Ravenna, Sand Point, Bryant, Windermere, Laurelhurst, Roosevelt, University of Washington, Wedgwood, Victory Heights, Matthews Beach, Meadowbrook, Olympic Hills, Cedar Park, Pinehurst, Maple Leaf, University District, University Heights |
| Magnolia/Queen Anne | East Queen Anne, West Queen Anne, Lower Queen Anne, North Queen Anne, Westlake, Lawton Park, Briarcliff, Southeast Magnolia, Interbay |
| Central Seattle | Eastlake, Madrona, Harrison/Denny-Blaine, Minor, Leschi, Mann, First Hill, Yesler Terrace, Portage Bay, Montlake, Madison Park, Broadway, Stevens |
| Downtown Seattle | South Lake Union, Pike-Market, Belltown, International District, Central Business District, Pioneer Square, Denny Triangle |
| West Seattle | South Park, Seaview, Gatewood, Arbor Heights, Alki, North Admiral, Fairmount Park, Genesee, Fauntleroy, Highland Park, North Delridge, Riverview, High Point, South Delridge, Roxhill |
| South/Southeast Seattle | Atlantic, SODO, Georgetown, North Beacon Hill, Mid-Beacon Hill, South Beacon Hill, Holly Park, Brighton, Dunlap, Rainier Beach, Rainier View, Mount Baker, Columbia City, Seward Park, Industrial District, Harbor Island |
We will now create our bipartite graphs to visualize the relationships between pest species and neighborhoods. We will analyze the bipartite network structure and explore the patterns of pest sightings across different regions of Seattle.
We will be using the bipartiteD3 package to create
interactive bipartite graphs, the bipartite package for
analyzing bipartite networks, and RColorBrewer for creating
a custom color palette.
# first we have to convert our data, which is currently still an sf object, back to a regular data frame
# in this step we can also use the select function to get rid of the columns we no longer need
sea_pests_df <- as.data.frame(st_drop_geometry(pest_neighborhoods)) %>%
select(Date, Season, Target, Neighborhood)
# custom colors using RColorBrewer's Paired palette
paired_colors <- brewer.pal(12, "Paired")
# manually selecting colors
custom_colors <- c(
"Ants" = paired_colors[1],
"Rodents" = paired_colors[3],
"Cockroaches" = paired_colors[5],
"Biting Insects" = paired_colors[4],
"Spiders" = paired_colors[10],
"Flying Insects" = paired_colors[9],
"Storage and Structure Pests" = paired_colors[7],
"Stinging Insects" = paired_colors[8],
"Misc Crawling Insects" = paired_colors[6]
)
# function to create bipartite graph for a given season using bipartiteD3 with sorting and coloring
create_bipartiteD3_graph <- function(data, season = NULL) {
if (!is.null(season)) {
# Filter data for the given season
data <- data %>% filter(Season == season)
}
# creating a matrix of sightings
sightings_matrix <- data %>%
group_by(Target, Neighborhood) %>%
summarise(Sightings = n(), .groups = 'drop') %>%
pivot_wider(names_from = Neighborhood, values_from = Sightings, values_fill = 0) %>%
column_to_rownames("Target") %>%
as.matrix()
# sorting primary nodes
sort_primary <- data %>%
group_by(Target) %>%
summarise(Total = n(), .groups = 'drop') %>%
arrange(desc(Total)) %>%
pull(Target)
# sorting secondary nodes
sort_secondary <- data %>%
group_by(Neighborhood) %>%
summarise(Total = n(), .groups = 'drop') %>%
arrange(desc(Total)) %>%
pull(Neighborhood)
# creating bipartite graph using bipartiteD3 with custom colors
bipartite_D3(
sightings_matrix,
PrimaryLab = "Pest Type",
SecondaryLab = "Neighborhood",
SiteNames = if (is.null(season)) "Bipartite Graph of Seattle Pest Sightings in 2023" else paste("Bipartite Graph of Seattle Pest Sightings in", season, "2023"),
SortPrimary = sort_primary,
SortSecondary = sort_secondary,
colouroption = "manual",
NamedColourVector = custom_colors,
ColourBy = 1,
PercentageDecimals = 2,
MainFigSize = c(800, 475), # main figure size
IndivFigSize = c(200, 400), # individual figure size
BoxLabPos = c(35, 35), # label positions (excluding SiteNames, PrimaryLab, and SecondaryLab)
PercPos = c(240, 210), # percentage positions
MinWidth = 0, # min width of bars
Pad = 8 # padding between bars
)
}
Now that we have our Bipartite Function made we will start by creating a bipartite graph for the entire year 2023 to visualize the overall patterns of pest sightings in Seattle.
The graph will show the relationships between pest species and neighborhoods, highlighting the distribution of sightings across different regions of the city.
The percentages on the graph represent the proportion of sightings for each pest species in a particular neighborhood. You can hover over a bar to see a better view of a specific distribution (on either the pest or neighborhood side).
The Pest Types are color-coded for easy identification, and both node types are sorted based on the total distribution percentages (descending).
# creating a bipartite graph for the entire year
create_bipartiteD3_graph(sea_pests_df)
We will now create bipartite graphs for each season to explore the seasonal variations in pest sightings across Seattle. The graphs will show the distribution of pest species in different neighborhoods during each season.
# creating bipartite graphs for each season
create_bipartiteD3_graph(sea_pests_df, season = "Winter")
# creating bipartite graphs for each season
create_bipartiteD3_graph(sea_pests_df, season = "Spring")
# creating bipartite graphs for each season
create_bipartiteD3_graph(sea_pests_df, season = "Summer")
# creating bipartite graphs for each season
create_bipartiteD3_graph(sea_pests_df, season = "Fall")
The annual bipartite graph and seasonal graphs provided unique insights into the distribution of pests in Seattle and how those distributions change throughout the year.
I found the Bipartite graphs to be particularly useful for representing my two-mode network, where I had two distinct sets of nodes and my edges connected these nodes from one set to the other. This visualization technique allowed me to clearly see the relationships between pest species and neighborhoods, highlighting the distribution patterns and prevalence of different pests across Seattle.
To simplify the visualization and make the graphs more readable, we grouped the pest species and neighborhoods into broader categories. This aggregation helps in focusing on general trends and patterns rather than getting lost in the details of individual pest species or sub-neighborhoods.
case_when function from the
dplyr package.I used the bipartiteD3 package in R to create
interactive bipartite graphs. This package allows for dynamic and
visually appealing network visualizations, which can help in better
understanding the relationships and patterns within the data.
I found some very useful information from this site to help me get my bipartite plots formatted and working.
bipartiteD3 package allows for dynamic interaction with the
graph, making it easier to explore and understand the data.bipartiteD3
package has some limitations when it comes to customizing the title and
main labels (“Pest Type” and “Neighborhood”). These elements are not as
clear as they could be due to restrictions in the package’s
settings.bipartiteD3 package is still quite nice
and I was still able to make some adjustments.This project has given me great insights into the complexities of data cleaning, preparation, and visualization. I discovered that the majority of my time, roughly 90%, was spent on cleaning and preparing the data for analysis. I encountered several roadblocks during this process, requiring creative workarounds to ensure the data was accurate and usable.
Initially, I experimented with other visualization methods such as
igraph and ggplot2 for the bipartite graph.
However, I found that bipartiteD3 provided the most
effective way to visualize the relationships between pest species and
neighborhoods dynamically. The interactivity and customization options
offered by bipartiteD3 made it the ideal choice for this
project.
Despite my efforts, I ran out of time to incorporate a more detailed geospatial analysis/visualization beyond the neighborhood classifications. I also intended to apply some of the network measures learned in class to this data, but time constraints prevented me from doing so. Still, I believe the visualizations created here provided valuable information and a strong foundation for future work.
Working with real-world data from my own job was an incredible opportunity. It allowed me to apply theoretical concepts to practical problems, enhancing my understanding and skills in data analysis and visualization. Although this project is being submitted now, I plan to continue refining and expanding upon it.
Future work will include improving the formatting and content of this RMarkdown document, which currently feels rushed and cluttered in parts. I aim to reduce redundancy and enhance its clarity. Beyond these initial changes, I am excited to continue exploring network measures and I will attempt to apply them to this dataset, hopefully, gaining additional information that I will find useful. Incorporating more detailed geospatial analysis/visualization aspects is also a goal of mine, as I think it would be interesting to get an alternative view/perspective of the spatial distribution of pests in Seattle.
Ultimately, while I encountered several limitations primarily related to time, I believe that with patience and a willingness to continue learning, these barriers will not severely restrict the future developments of my work with this data. What I learned from this project will guide me in my continued exploration and application of network analysis and visualization techniques.
This project was really fun, and I am excited to continue working on it. Thank you for another great quarter!