12 Month Analysis U.S. National Oceanic and Atmospheric Administration’s (NOAA) storm database (JUL 2024 - JUN 2025)

The project seeks to identify relationships and links between data in the most recent 12 months of data available from the U.S. National Oceanic and Atmospheric Administration’s (NOAA) storm database to inform local government leaders the ability to make policy and community preparations to prioritize resources for various types of events based on historical data.

Note: The raw code was left in this project to allow for reproducible results to enhance opportunities for collaboration and additional study, including as new data becomes available in future years.

Synopsis

As of the creation of this project in NOV 2025, only JAN-JUN data was available from 2025, which was merged with JUL-DEC 2024 data to give the most recent 12 months of data for Emergency Managers and Local/Regional leaders to use when making decisions about how to prepare for future disasters and events. This study is particularly useful to newly elected officials or newly hired individuals who do not have much historical reference for the threats in their region. The study identifies the most common events in each state as well as the events that produce the highest death and injury counts, both directly and indirectly, as well as the identifying property damage annually. This project identifies the most deadly weather events in the U.S. as well as which states have the most casualties (deaths and injuries). BY analyzing the property damage (in U.S. Dollars) over the most recent 12-month period, Public officials get a better understanding of how much to expect to spend annually from a financial perspective on weather response events. This helps drive the need for federal grants or alternate funding sources to balance the budget. Ultimately, this project only highlights the very basic most prominent concerns for each state and which events produce the most casualties in each month. This gives a baseline understanding to public and private officials that are new to the field of Emergency Management. More in depth study of this data can develop specific states/region estimates with more historical clarity.

Data Processing

This project begins with 3 sets of raw data from both the 2024 and 2025 years, downloaded from the U.S. National Oceanic and Atmospheric Administration’s (NOAA) storm database, located at https://www.ncei.noaa.gov/pub/data/swdi/stormevents/csvfiles/. The most recent data available was used for “details”, “fatalities” and “locations”. In this case, The 2024 data covered the entire year of 2024 while only the January through June data was available for 2025. To get the most recent 12 month window of data, the JAN-JUN 2024 data was removed and the remaining 2024 data was combined with the 2025 which only included JAN-JUN. This results in a 12-month data set of July 2024 - June 2025. Using the most recent data allows the most current analysis of storms and environmental threats across the various regions in the United States.

Joining raw data

Those raw data files are joined by event ID number using the following R code:

# Load necessary libraries
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(readr)

# Define the folder path
folder_path <- "C:/Users/micha/OneDrive/Desktop/DAT511ONL/Final Project"

# Define the file paths for the unzipped CSV files
## 2024 data (JAN - DEC 2024)
details_file_24 <- file.path(folder_path, "StormEvents_details-ftp_v1.0_d2024_c20251118.csv.gz")
fatalities_file_24 <- file.path(folder_path, "StormEvents_fatalities-ftp_v1.0_d2024_c20251118.csv.gz")
locations_file_24 <- file.path(folder_path, "StormEvents_locations-ftp_v1.0_d2024_c20251118.csv.gz")

## 2025 data (JAN - JUN 2025)
details_file_25 <- file.path(folder_path, "StormEvents_details-ftp_v1.0_d2025_c20251118.csv.gz")
fatalities_file_25 <- file.path(folder_path, "StormEvents_fatalities-ftp_v1.0_d2025_c20251118.csv.gz")
locations_file_25 <- file.path(folder_path, "StormEvents_locations-ftp_v1.0_d2025_c20251118.csv.gz")

# Load the CSV files into R
## 2024
details_24 <- read_csv(details_file_24)
## Warning: One or more parsing issues, call `problems()` on your data frame for details,
## e.g.:
##   dat <- vroom(...)
##   problems(dat)
## Rows: 69502 Columns: 51
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): STATE, MONTH_NAME, EVENT_TYPE, CZ_TYPE, CZ_NAME, WFO, BEGIN_DATE_T...
## dbl (24): BEGIN_YEARMONTH, BEGIN_DAY, BEGIN_TIME, END_YEARMONTH, END_DAY, EN...
## lgl  (1): CATEGORY
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
fatalities_24 <- read_csv(fatalities_file_24)
## Rows: 998 Columns: 11
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (4): FATALITY_TYPE, FATALITY_DATE, FATALITY_SEX, FATALITY_LOCATION
## dbl (7): FAT_YEARMONTH, FAT_DAY, FAT_TIME, FATALITY_ID, EVENT_ID, FATALITY_A...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
locations_24 <- read_csv(locations_file_24)
## Rows: 42156 Columns: 11
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): AZIMUTH, LOCATION
## dbl (9): YEARMONTH, EPISODE_ID, EVENT_ID, LOCATION_INDEX, RANGE, LATITUDE, L...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
## 2025
details_25 <- read_csv(details_file_25)
## Rows: 44721 Columns: 51
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): STATE, MONTH_NAME, EVENT_TYPE, CZ_TYPE, CZ_NAME, WFO, BEGIN_DATE_T...
## dbl (24): BEGIN_YEARMONTH, BEGIN_DAY, BEGIN_TIME, END_YEARMONTH, END_DAY, EN...
## lgl  (1): CATEGORY
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
fatalities_25 <- read_csv(fatalities_file_25)
## Rows: 423 Columns: 11
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (4): FATALITY_TYPE, FATALITY_DATE, FATALITY_SEX, FATALITY_LOCATION
## dbl (7): FAT_YEARMONTH, FAT_DAY, FAT_TIME, FATALITY_ID, EVENT_ID, FATALITY_A...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
locations_25 <- read_csv(locations_file_25)
## Rows: 31130 Columns: 11
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): AZIMUTH, LOCATION
## dbl (9): YEARMONTH, EPISODE_ID, EVENT_ID, LOCATION_INDEX, RANGE, LATITUDE, L...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# Join the datasets by EVENT_ID
## 2024
joined_data_24 <- details_24 %>%
  left_join(locations_24, by = "EVENT_ID") %>%
  left_join(fatalities_24, by = "EVENT_ID")
## Warning in left_join(., fatalities_24, by = "EVENT_ID"): Detected an unexpected many-to-many relationship between `x` and `y`.
## ℹ Row 832 of `x` matches multiple rows in `y`.
## ℹ Row 528 of `y` matches multiple rows in `x`.
## ℹ If a many-to-many relationship is expected, set `relationship =
##   "many-to-many"` to silence this warning.
## 2025
joined_data_25 <- details_25 %>%
  left_join(locations_25, by = "EVENT_ID") %>%
  left_join(fatalities_25, by = "EVENT_ID")
## Warning in left_join(., fatalities_25, by = "EVENT_ID"): Detected an unexpected many-to-many relationship between `x` and `y`.
## ℹ Row 896 of `x` matches multiple rows in `y`.
## ℹ Row 325 of `y` matches multiple rows in `x`.
## ℹ If a many-to-many relationship is expected, set `relationship =
##   "many-to-many"` to silence this warning.
# Save the joined data to a new CSV file
## 2024
output_file_24 <- file.path(folder_path, "StormEvents_joined_data_24.csv")
write_csv(joined_data_24, output_file_24)

## 2025
output_file_25 <- file.path(folder_path, "StormEvents_joined_data_25.csv")
write_csv(joined_data_25, output_file_25)

# Inform the user
message("2024 Joined data saved to: ", output_file_24)
## 2024 Joined data saved to: C:/Users/micha/OneDrive/Desktop/DAT511ONL/Final Project/StormEvents_joined_data_24.csv
message("2025 Joined data saved to: ", output_file_25)
## 2025 Joined data saved to: C:/Users/micha/OneDrive/Desktop/DAT511ONL/Final Project/StormEvents_joined_data_25.csv
# Optional: View the first few rows of the joined data
## 2024
print(head(joined_data_24))
## # A tibble: 6 × 71
##   BEGIN_YEARMONTH BEGIN_DAY BEGIN_TIME END_YEARMONTH END_DAY END_TIME
##             <dbl>     <dbl>      <dbl>         <dbl>   <dbl>    <dbl>
## 1          202404        30       2033        202404      30     2033
## 2          202407         1          0        202407       5      900
## 3          202411        16        230        202411      18     1421
## 4          202405        22       1230        202405      22     1615
## 5          202405        21       1200        202405      21     1530
## 6          202405        24       1405        202405      24     1410
## # ℹ 65 more variables: EPISODE_ID.x <dbl>, EVENT_ID <dbl>, STATE <chr>,
## #   STATE_FIPS <dbl>, YEAR <dbl>, MONTH_NAME <chr>, EVENT_TYPE <chr>,
## #   CZ_TYPE <chr>, CZ_FIPS <dbl>, CZ_NAME <chr>, WFO <chr>,
## #   BEGIN_DATE_TIME <chr>, CZ_TIMEZONE <chr>, END_DATE_TIME <chr>,
## #   INJURIES_DIRECT <dbl>, INJURIES_INDIRECT <dbl>, DEATHS_DIRECT <dbl>,
## #   DEATHS_INDIRECT <dbl>, DAMAGE_PROPERTY <chr>, DAMAGE_CROPS <chr>,
## #   SOURCE <chr>, MAGNITUDE <dbl>, MAGNITUDE_TYPE <chr>, FLOOD_CAUSE <chr>, …
## 2025
print(head(joined_data_25))
## # A tibble: 6 × 71
##   BEGIN_YEARMONTH BEGIN_DAY BEGIN_TIME END_YEARMONTH END_DAY END_TIME
##             <dbl>     <dbl>      <dbl>         <dbl>   <dbl>    <dbl>
## 1          202503        31       1104        202503      31     1106
## 2          202503        30       1552        202503      30     1555
## 3          202501         5       1800        202501       6     2227
## 4          202501         3       1300        202501       3     1900
## 5          202501         3       1300        202501       3     1900
## 6          202501         3       1300        202501       3     1900
## # ℹ 65 more variables: EPISODE_ID.x <dbl>, EVENT_ID <dbl>, STATE <chr>,
## #   STATE_FIPS <dbl>, YEAR <dbl>, MONTH_NAME <chr>, EVENT_TYPE <chr>,
## #   CZ_TYPE <chr>, CZ_FIPS <dbl>, CZ_NAME <chr>, WFO <chr>,
## #   BEGIN_DATE_TIME <chr>, CZ_TIMEZONE <chr>, END_DATE_TIME <chr>,
## #   INJURIES_DIRECT <dbl>, INJURIES_INDIRECT <dbl>, DEATHS_DIRECT <dbl>,
## #   DEATHS_INDIRECT <dbl>, DAMAGE_PROPERTY <chr>, DAMAGE_CROPS <chr>,
## #   SOURCE <chr>, MAGNITUDE <dbl>, MAGNITUDE_TYPE <chr>, FLOOD_CAUSE <chr>, …
# Since 2024 is 12 months and 2025 is the first 6 months, we will remove the first 6 months of 2024 data before merging the two files to obtain the most recent 12 month window of data

## Strip 2024 of first 6 months
joined_data_24_strip <- joined_data_24[joined_data_24$MONTH_NAME %in% c("July", "August", "September", "October", "November", "December"), ]


## 2024
output_file_24_strip <- file.path(folder_path, "StormEvents_joined_data_24_strip.csv")
write_csv(joined_data_24_strip, output_file_24_strip)


## Merge final two csv files:
### read data (one restated for cleanliness)
data_25 <- read.csv("StormEvents_joined_data_25.csv")
data_24 <- read.csv("StormEvents_joined_data_24_strip.csv")

### Join data
joined_data <- bind_rows(data_25, data_24)

### Output of combined file
output_file_merged <- file.path(folder_path, "StormEvents_joined_data.csv")
write_csv(joined_data, output_file_merged)

### Inform the user
message("JUL 2024 - JUN 2025 files Merged data saved to: ", output_file_merged)
## JUL 2024 - JUN 2025 files Merged data saved to: C:/Users/micha/OneDrive/Desktop/DAT511ONL/Final Project/StormEvents_joined_data.csv
# Optional: View the first few rows of the joined data
## 2024
print(head(joined_data))
##   BEGIN_YEARMONTH BEGIN_DAY BEGIN_TIME END_YEARMONTH END_DAY END_TIME
## 1          202503        31       1104        202503      31     1106
## 2          202503        30       1552        202503      30     1555
## 3          202501         5       1800        202501       6     2227
## 4          202501         3       1300        202501       3     1900
## 5          202501         3       1300        202501       3     1900
## 6          202501         3       1300        202501       3     1900
##   EPISODE_ID.x EVENT_ID    STATE STATE_FIPS YEAR MONTH_NAME        EVENT_TYPE
## 1       201366  1252415  GEORGIA         13 2025      March Thunderstorm Wind
## 2       200337  1241136 MICHIGAN         26 2025      March           Tornado
## 3       197733  1222851 VIRGINIA         51 2025    January      Winter Storm
## 4       197761  1223112 MARYLAND         24 2025    January    Winter Weather
## 5       197761  1223113 MARYLAND         24 2025    January    Winter Weather
## 6       197761  1223114 MARYLAND         24 2025    January    Winter Weather
##   CZ_TYPE CZ_FIPS                          CZ_NAME WFO    BEGIN_DATE_TIME
## 1       C      45                          CARROLL FFC 31-MAR-25 11:04:00
## 2       C      27                             CASS IWX 30-MAR-25 15:52:00
## 3       Z      56                     SPOTSYLVANIA LWX 05-JAN-25 18:00:00
## 4       Z     506     CENTRAL AND SOUTHEAST HOWARD LWX 03-JAN-25 13:00:00
## 5       Z     504 CENTRAL AND SOUTHEAST MONTGOMERY LWX 03-JAN-25 13:00:00
## 6       Z     503             NORTHWEST MONTGOMERY LWX 03-JAN-25 13:00:00
##   CZ_TIMEZONE      END_DATE_TIME INJURIES_DIRECT INJURIES_INDIRECT
## 1       EST-5 31-MAR-25 11:06:00               0                 0
## 2       EST-5 30-MAR-25 15:55:00               0                 0
## 3       EST-5 06-JAN-25 22:27:00               0                 0
## 4       EST-5 03-JAN-25 19:00:00               0                 0
## 5       EST-5 03-JAN-25 19:00:00               0                 0
## 6       EST-5 03-JAN-25 19:00:00               0                 0
##   DEATHS_DIRECT DEATHS_INDIRECT DAMAGE_PROPERTY DAMAGE_CROPS            SOURCE
## 1             0               0           1.00K         <NA> Emergency Manager
## 2             0               0         100.00K        0.00K  NWS Storm Survey
## 3             0               0            <NA>         <NA>   Trained Spotter
## 4             0               0            <NA>         <NA>   Trained Spotter
## 5             0               0            <NA>         <NA>   Trained Spotter
## 6             0               0            <NA>         <NA>   Trained Spotter
##   MAGNITUDE MAGNITUDE_TYPE FLOOD_CAUSE CATEGORY TOR_F_SCALE TOR_LENGTH
## 1        52             EG        <NA>       NA        <NA>         NA
## 2        NA           <NA>        <NA>       NA         EF1       2.59
## 3        NA           <NA>        <NA>       NA        <NA>         NA
## 4        NA           <NA>        <NA>       NA        <NA>         NA
## 5        NA           <NA>        <NA>       NA        <NA>         NA
## 6        NA           <NA>        <NA>       NA        <NA>         NA
##   TOR_WIDTH TOR_OTHER_WFO TOR_OTHER_CZ_STATE TOR_OTHER_CZ_FIPS
## 1        NA          <NA>               <NA>                NA
## 2       100          <NA>               <NA>                NA
## 3        NA          <NA>               <NA>                NA
## 4        NA          <NA>               <NA>                NA
## 5        NA          <NA>               <NA>                NA
## 6        NA          <NA>               <NA>                NA
##   TOR_OTHER_CZ_NAME BEGIN_RANGE BEGIN_AZIMUTH BEGIN_LOCATION END_RANGE
## 1              <NA>           2             W           TYUS         2
## 2              <NA>           1            SW    EDWARDSBURG         1
## 3              <NA>          NA          <NA>           <NA>        NA
## 4              <NA>          NA          <NA>           <NA>        NA
## 5              <NA>          NA          <NA>           <NA>        NA
## 6              <NA>          NA          <NA>           <NA>        NA
##   END_AZIMUTH END_LOCATION BEGIN_LAT BEGIN_LON END_LAT END_LON
## 1           W         TYUS   33.4757   -85.238 33.4757 -85.238
## 2         NNE  EDWARDSBURG   41.7900   -86.100 41.8200 -86.070
## 3        <NA>         <NA>        NA        NA      NA      NA
## 4        <NA>         <NA>        NA        NA      NA      NA
## 5        <NA>         <NA>        NA        NA      NA      NA
## 6        <NA>         <NA>        NA        NA      NA      NA
##                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              EPISODE_NARRATIVE
## 1                                                                                                                                                                                                                                                                                                                                                                                           A cold-front initiated a line of thunderstorms across north and central GA through the afternoon hours of the 31st. Storms brought damaging winds along the I20 corridor and south as well as six quick spin-up tornadoes. The strongest being an EF1 between McDonough and Stockbridge crossing Hwy 75. There were also a couple reports of quarter size hail southeast of Macon.
## 2                                                                                                                                                                                                                                                                                                                                                                                                                                                   A cold front pushed into the area during the afternoon and evening hours, interacting with  decent shear and MLCAPE to allow for numerous thunderstorm development. Pockets of damaging winds occurred along with a total of six confirmed tornadoes (three in far southern Lower Michigan and three in northern Indiana).
## 3 An area of low pressure tracked across southern Virginia bringing the first widespread accumulating snow of the season. Snow overspread the area during the late evening hours of January 5th into the overnight. Snow overspread the area during the late evening hours of January 5th into the overnight. This continued steady through mid-morning. A lull occurred during the afternoon with a few snow showers. Another round of snow on the back side of the upper level low moved in during the evening bringing additional accumulations. This resulted in a swath of 6 to 12 inches of snow, with the higher totals in the northern Shenandoah Valley east towards Prince William County. Winds gusted to 45 mph resulting in blowing snow at the end of the storm.
## 4                                                                                                                                                                                                                                                                                                                                                                                                                                   An area of low pressure moved off into New England bringing a cold front through Maryland. Upslope snow showers and squalls ensued in western Maryland bringing accumulations of six to ten inches. Snow showers and squalls along the front impacted portions of the rest of the state bringing accumulations of a coating to two inches.
## 5                                                                                                                                                                                                                                                                                                                                                                                                                                   An area of low pressure moved off into New England bringing a cold front through Maryland. Upslope snow showers and squalls ensued in western Maryland bringing accumulations of six to ten inches. Snow showers and squalls along the front impacted portions of the rest of the state bringing accumulations of a coating to two inches.
## 6                                                                                                                                                                                                                                                                                                                                                                                                                                   An area of low pressure moved off into New England bringing a cold front through Maryland. Upslope snow showers and squalls ensued in western Maryland bringing accumulations of six to ten inches. Snow showers and squalls along the front impacted portions of the rest of the state bringing accumulations of a coating to two inches.
##                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              EVENT_NARRATIVE
## 1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Tree down at the intersection of highway 5 and old columbus road.
## 2 A brief EF-1 tornado was confirmed in Edwardsburg, MI on March 30th, 2025. The tornado started in a field west of Conrad Rd, snapping and uprooting trees as it moved northeast towards the Edwardsburg Primary School, where EF-0 damage was noted. The tornado continued to the northeast and intensified, where several homes and businesses sustained damage on the east side of Pleasant Lake. The Starboard Choice Marina building sustained roof damage, a boat lift and dock were removed from the lake and flipped over, and a few boats were damaged as well, including one that was flipped and lifted over a fence. The most intense damage was seen along Dailey Road, where numerous large trees were snapped and uprooted, with estimated peak wind speeds of 90 mph. Overall, the tornado was on the ground for 3 minutes and had a peak intensity of EF-1. There were also areas of straight-line wind damage noted throughout Edwardsburg, indicative that the tornado was likely embedded within the line of storms that moved through.
## 3                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       <NA>
## 4                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       <NA>
## 5                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       <NA>
## 6                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       <NA>
##   DATA_SOURCE YEARMONTH EPISODE_ID.y LOCATION_INDEX RANGE AZIMUTH LOCATION
## 1         CSV        NA           NA             NA    NA    <NA>     <NA>
## 2         CSV        NA           NA             NA    NA    <NA>     <NA>
## 3         CSV        NA           NA             NA    NA    <NA>     <NA>
## 4         CSV        NA           NA             NA    NA    <NA>     <NA>
## 5         CSV        NA           NA             NA    NA    <NA>     <NA>
## 6         CSV        NA           NA             NA    NA    <NA>     <NA>
##   LATITUDE LONGITUDE LAT2 LON2 FAT_YEARMONTH FAT_DAY FAT_TIME FATALITY_ID
## 1       NA        NA   NA   NA            NA      NA       NA          NA
## 2       NA        NA   NA   NA            NA      NA       NA          NA
## 3       NA        NA   NA   NA            NA      NA       NA          NA
## 4       NA        NA   NA   NA            NA      NA       NA          NA
## 5       NA        NA   NA   NA            NA      NA       NA          NA
## 6       NA        NA   NA   NA            NA      NA       NA          NA
##   FATALITY_TYPE FATALITY_DATE FATALITY_AGE FATALITY_SEX FATALITY_LOCATION
## 1          <NA>          <NA>           NA         <NA>              <NA>
## 2          <NA>          <NA>           NA         <NA>              <NA>
## 3          <NA>          <NA>           NA         <NA>              <NA>
## 4          <NA>          <NA>           NA         <NA>              <NA>
## 5          <NA>          <NA>           NA         <NA>              <NA>
## 6          <NA>          <NA>           NA         <NA>              <NA>
##   EVENT_YEARMONTH
## 1              NA
## 2              NA
## 3              NA
## 4              NA
## 5              NA
## 6              NA

The output of this code is a single joined raw data document titled “StormEvents_joined_data.csv”.

The joined data csv file now contains all events from JUL 2024 - JUN 2025 and is ready for processing and analysis.

Results

Population Health Impacts

To determine which types of events across the United States, are most harmful with respect to population health, the joined data file is analyzed in a quad graph using the below code to list events that cause the most deaths and injuries, by both their direct and indirect effects. The Direct effects are injuries and deaths that are caused during the storm/event, while the indirect deaths and injuries account for those secondary casualties which includes longer incubation time. The casualties during an event are likely only reduced through preparation and investment in propositioning of necessary equipment and training of personnel as mobility during an event to respond to a disaster are often limited with roads washed out or impassable. However, indirect secondary casualty reducing events can often be significantly reduced through a well-rehearsed and well-supported response plan, reaching victims quickly and restoring power to affected areas.

library(ggplot2)
library(patchwork)
par(mfrow = c(2, 2)) # Initiates the 4 quad graphic

#| label: Count of Direct Deaths by Event Type
total_deaths_direct <- joined_data %>%
  group_by(EVENT_TYPE) %>%
  summarise(total_deaths = sum(DEATHS_DIRECT, na.rm = TRUE)) %>%
  arrange(desc(total_deaths))
plot1 <- ggplot(total_deaths_direct, aes(x = reorder(EVENT_TYPE, -total_deaths), y = total_deaths)) +
  geom_col(fill = "red") +
  labs(title = "1a. # Direct Deaths by Event Type", x = "Event Type", y = "Total Direct Deaths") +
  theme_bw() +
  theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle = 45, hjust = 1, size = 3))

#| label: Count of Indirect Deaths by Event Type
total_deaths_indirect <- joined_data %>%
  group_by(EVENT_TYPE) %>%
  summarise(total_deaths = sum(DEATHS_INDIRECT, na.rm = TRUE)) %>%
  arrange(desc(total_deaths))
plot2 <- ggplot(total_deaths_indirect, aes(x = reorder(EVENT_TYPE, -total_deaths), y = total_deaths)) +
  geom_col(fill = "orange") +
  labs(title = "1b. # Indirect Deaths by Event Type", x = "Event Type", y = "Total Indirect Deaths") +
  theme_bw() +
  theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle = 45, hjust = 1, size = 3))

#| label: Count of Direct Injuries by Event Type
total_injuries_direct <- joined_data %>%
  group_by(EVENT_TYPE) %>%
  summarise(total_injuries = sum(INJURIES_DIRECT, na.rm = TRUE)) %>%
  arrange(desc(total_injuries))
plot3 <- ggplot(total_injuries_direct, aes(x = reorder(EVENT_TYPE, -total_injuries), y = total_injuries)) +
  geom_col(fill = "blue") +
  labs(title = "1c. T# Direct Injuries by Event Type", x = "Event Type", y = "Total Direct Injuries") +
  theme_bw() +
  theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle = 45, hjust = 1, size = 3))

#| label: Count of Indirect Injuries by Event Type
total_injuries_indirect <- joined_data %>%
  group_by(EVENT_TYPE) %>%
  summarise(total_injuries = sum(INJURIES_INDIRECT, na.rm = TRUE)) %>%
  arrange(desc(total_injuries))
plot4 <- ggplot(total_injuries_indirect, aes(x = reorder(EVENT_TYPE, -total_injuries), y = total_injuries)) +
  geom_col(fill = "brown") +
  labs(title = "1d. # Indirect Injuries by Event Type", x = "Event Type", y = "Total Indirect Injuries") +
  theme_bw() +
  theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle = 45, hjust = 1, size = 3))
(plot1 + plot2) / (plot3 + plot4)

Figure 1a-d. Number of deaths and injuries (direct and indirect) by type of event across the United States in a year (JUL 2024 - JUN 2025)

The charts in Figure 1a-1d show the highest casualty producing events across the U.S. for the studied 12-month period and each category adjusts the graph to list the highest casualty producing events in descending order. This data combined with additional study for which events occur in which states and which time of year can assist Emergency Managers and public/private officials to best allocate their resources to prepare for future events.

Flash Floods, Excessive Heat and Wildfire produce the most direct deaths while excessive Heat produces the most indirect deaths. Tornado, Wildfire Heat and Hurricanes produce the most direct injuries while Dust Storms and Winter Weather produce the most indirect injuries.

Any state that deals with heat and dry areas should expect potentially devastating impacts based on the death rates associated with heat-related events, with coastal and cold climate areas preparing for Hurricanes and Tornadoes respectively.

Most Frequently Occuring Event in Each State

The below code identifies produces a heat-map, showing the most frequent events in each state. The states are ordered, listing the states with the most number of events first and the remainder following in deceasing order based on quantity of events. It is important to note that not all these events produce casualties (deaths or injures) or property damage. However, the more likely an event is to occur, the more confident local leaders can be that it will occur again and may have devastating impacts in the future.

tbl <- table(joined_data$EVENT_TYPE, joined_data$STATE)
tile_df <- data.frame(tbl)
tile_df <- tile_df[order(-tile_df$Freq), ]  # Order frequency

ggplot(tile_df, mapping = aes(x = reorder(Var2, -Freq), y = Var1)) +
  geom_tile(mapping = aes(fill = Freq)) +
  labs(title = "Event Type by State", x = "State", y = "Event Type") +
  theme_bw() +
  theme(plot.title = element_text(hjust = 0.5), 
        axis.text.x = element_text(angle = 45, hjust = 1, size = 3),
        axis.text.y = element_text(angle = 45, hjust = 1, size = 3),
        plot.margin = margin(1, 1, 1, 1, "cm"),
        panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank()) +
  coord_fixed(ratio = 1)

Figure 2. Heat-Map of State vs Weather event type, ordered with the states with the most events listed first and other states in descending order of number of events. Those events with the highest frequency in each state are visible in the heat map with the brightest colors

While Texas, West Virginia, Missouri, Virginia and Tennessee are the top 5 states for the most weather related events, those numbers only indicate the frequency of events happening and not the damage or casualties associated with those events. Neighboring states to these higher risk states should also prepare both in case the events crosses boarders into their own territory, but also to be able to provide inter-state assistance through mutual aide agreements as neighboring states are likely the first to be able to response from outside a state, once that state’s resources are used in a disaster response effort. Preparing mutual aid agreements before events occur will greatly enhance cooperation and coordinated action among affected and responding state capabilities (people, equipment, training).

Months with the Highest Frequency of Events, by Type

The below code produces an interactive graph that allows the user to click on specific event types in the legend and highlight when those specific events occur.

library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
joined_data$MONTH_NAME <- factor(joined_data$MONTH_NAME, levels = month.name) 

p <- ggplot(joined_data, aes(x = MONTH_NAME, fill = EVENT_TYPE)) +
  geom_bar(position = "stack") +
  labs(title = "Most Common Events by Month", x = "Month", y = "Count", fill = "Event Type") +
  theme_bw() +
  theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle = 45, hjust = 1))

ggplotly(p)

Figure 3. Most Common Events by Month (Interactive)

The overall bar chart depicts which months have the most events, but this only discusses frequency of events rather than impact and damage associated with those events. The bar graph shows that summer months have the highest number of events, specifically in June, with October being the least likely month for events as it is in shoulder season, between the extremes of summer and winter weather. That makes October a great month for Emergency Manager cooperation and development/signing of mutual aid agreements as well as budget proposals for the next year. This further makes sense given that OCT/NOV is the time period that the International Association of Emergency Managers (IAEM) holds their annual conference, in a time that is historically low in the U.S. for disaster events.

This chart can be misleading in terms of communicating the biggest problem events because it assesses the most likely events, but not the most dangerous. As such, if you click on “Hurricane” in the chart, it shows only a small bit of data in late summer. However, while few hurricanes typically occur annually in the U.S., each one can be extremely devastating to property damage and loss of life.

Another way to see this same data is to look at the frequency of events that occur and in which month those events occur. The below code for Figure 4 shows which events occur most often and ion which months those events occur.

joined_data$MONTH_NAME <- factor(joined_data$MONTH_NAME, levels = month.name) # ordered the results in month order starting with January
ordered_data <- joined_data %>%
  group_by(EVENT_TYPE, MONTH_NAME) %>%
  summarise(Count = n()) %>%
  arrange(desc(Count))
## `summarise()` has grouped output by 'EVENT_TYPE'. You can override using the
## `.groups` argument.
ggplot(ordered_data, aes(x = reorder(EVENT_TYPE, -Count), y = Count)) +
  geom_bar(aes(fill = MONTH_NAME), position = "stack", stat = "identity") +
  labs(title = "Number of Each Event by Month Frequency", x = "Event Type", y = "Count", fill = "Month") +
  theme_bw() +
  theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle = 45, hjust = 1, size = 5))

Figure 4. Number of weather event types in a year (JUL 2024 - JUN 2025) across the United States listed by frequency of occurrence in each month

The most common event type is Thunderstorm Winds, Flash Flood, Flood and Hail. These events are the most common, but are not necessarily the most deadly as observed in Figure 1a-1d. Emergency Managers and Officials in states that have more flooding and thunderstorms (as depicted in the Figure 2 heat-map will want to focus some attention on these most likely events, but may only need to warn civilians about certain events, which can continue to limit loss of life and property damage.

Property Damage

To round out the picture of where Emergency Managers and Officials should allocated assets, the below code produces a bar graph, depicting the total cost of each type of even annually in terms of property damage in U.S. Dollars.

#Change column data for Property Damage to numeric for easier use
joined_data$DAMAGE_PROPERTY <- as.numeric(gsub("K", "", joined_data$DAMAGE_PROPERTY)) * 1000
## Warning: NAs introduced by coercion
colnames(joined_data)[colnames(joined_data) == "DAMAGE_PROPERTY"] <- "DAMAGE_PROPERTY"

ordered_data <- joined_data %>%
  group_by(EVENT_TYPE) %>%
  summarise(Total_Damage = sum(as.numeric(DAMAGE_PROPERTY), na.rm = TRUE)) %>%
  arrange(desc(Total_Damage))

ggplot(ordered_data, aes(x = reorder(EVENT_TYPE, -Total_Damage), y = Total_Damage)) +
  geom_bar(stat = "identity", position = "stack", fill = "blue") +
  labs(title = "Most Common Events by Property Damage", x = "Event Type", y = "Total Property Damage ($USD)", fill = "Event Type") +
  scale_y_continuous(labels = scales::comma_format(scale = 1e-3, suffix = "K")) +
  theme_bw() +
  theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle = 45, hjust = 1, size = 5))
## Ignoring unknown labels:
## • fill : "Event Type"

Figure 5. Events Causing the most property damage in $USD in a year (JUL 2024 - JUN 2025) across the United States

Figure 5 shows the highest cost events annually are Flash Floods, Tornado and Thunderstorm Winds. These are events that cause significant property damage and cost the most to repair and recover. These are events that officials may want to consider requesting Federal Grants as these will be the most costly events. They could be single massive events like the 2011 Joplin, Missouri Tornado that caused nearly 3 billion of dollars of damage. Or they could be the sum of numerous smaller events such as Floods or Thunderstorm Winds, causing damage to homes and businesses across an entire community all at once or repeated over and over.

Quick Reference Table

For Emergency Managers and officials, the below code produces a table that depicts the actual number of deaths, injuries and property damage as well as the most common type of event for each state.

summary_table <- joined_data %>%
  group_by(STATE) %>%
  summarise(
    DEATHS_DIRECT = sum(DEATHS_DIRECT, na.rm = TRUE),
    DEATHS_INDIRECT = sum(DEATHS_INDIRECT, na.rm = TRUE),
    INJURIES_DIRECT = sum(INJURIES_DIRECT, na.rm = TRUE),
    INJURIES_INDIRECT = sum(INJURIES_INDIRECT, na.rm = TRUE),
    DAMAGE_PROPERTY = sum(DAMAGE_PROPERTY, na.rm = TRUE),
    EVENT_TYPE = names(sort(table(EVENT_TYPE), decreasing = TRUE))[1]
  )

colnames(summary_table) <- c("State", "Direct Deaths", "Indirect Deaths", "Direct Injuries", "Indirect Injuries", "Property Damage $", "Most Common Event Type") # Renames table columns to be more descriptive

knitr::kable(summary_table)
State Direct Deaths Indirect Deaths Direct Injuries Indirect Injuries Property Damage $ Most Common Event Type
ALABAMA 9 3 49 1 7708600 Thunderstorm Wind
ALASKA 9 0 25 0 81400 Flood
AMERICAN SAMOA 0 0 0 0 10318000 Flash Flood
ARIZONA 275 387 48 32 4093500 Flash Flood
ARKANSAS 1 0 31 0 15995800 Thunderstorm Wind
ATLANTIC NORTH 4 0 0 0 6000 Marine Thunderstorm Wind
ATLANTIC SOUTH 0 0 0 0 0 Marine Thunderstorm Wind
CALIFORNIA 1069 75 496 12 9587400 Flood
COLORADO 5 0 3 0 2043000 Hail
CONNECTICUT 5 0 0 0 1040900 Flash Flood
DELAWARE 1 0 4 0 233000 Thunderstorm Wind
DISTRICT OF COLUMBIA 0 0 0 0 758000 Thunderstorm Wind
E PACIFIC 0 0 0 0 0 Waterspout
FLORIDA 113 50 53 3 8888100 Flash Flood
GEORGIA 87 22 175 4 21301150 Thunderstorm Wind
GUAM 4 0 10 0 159850 Flash Flood
GUAM WATERS 16 0 12 0 0 Marine Strong Wind
GULF OF ALASKA 0 0 0 0 0 Marine Thunderstorm Wind
GULF OF MEXICO 0 0 1 0 5000 Marine Thunderstorm Wind
HAWAII 4 0 9 0 455000 Drought
IDAHO 1 4 9 3 2584650 Thunderstorm Wind
ILLINOIS 8 2 31 16 8669400 Thunderstorm Wind
INDIANA 14 2 39 0 47955450 Thunderstorm Wind
IOWA 0 10 1 11 2445100 Thunderstorm Wind
KANSAS 1 73 22 371 5649000 Thunderstorm Wind
KENTUCKY 14 10 39 0 9160150 Thunderstorm Wind
LAKE ERIE 2 2 0 0 500 Marine Thunderstorm Wind
LAKE HURON 0 0 0 0 0 Marine Thunderstorm Wind
LAKE MICHIGAN 1 0 1 0 0 Marine Thunderstorm Wind
LAKE ONTARIO 0 0 0 0 5000 Marine Thunderstorm Wind
LAKE ST CLAIR 0 0 0 0 0 Marine Thunderstorm Wind
LAKE SUPERIOR 0 0 0 0 0 Marine Thunderstorm Wind
LOUISIANA 7 8 21 3 14980750 Flash Flood
MAINE 0 0 0 0 11000 Winter Weather
MARYLAND 0 0 8 0 9598600 Thunderstorm Wind
MASSACHUSETTS 0 0 6 0 405600 Thunderstorm Wind
MICHIGAN 2 0 2 4 5243500 Thunderstorm Wind
MINNESOTA 0 2 2 10 2462900 Thunderstorm Wind
MISSISSIPPI 11 2 43 0 26379900 Thunderstorm Wind
MISSOURI 139 1 354 2 43202750 Thunderstorm Wind
MONTANA 0 40 13 29 951000 High Wind
NEBRASKA 2 5 22 2 10480000 Hail
NEVADA 1436 2164 0 0 207000 High Wind
NEW HAMPSHIRE 0 0 2 0 198000 Flash Flood
NEW JERSEY 0 0 166 0 1062500 Thunderstorm Wind
NEW MEXICO 18 12 4 28 18856250 Flash Flood
NEW YORK 27 3 8 14 29517050 Thunderstorm Wind
NORTH CAROLINA 732 2 48 0 19381650 Flash Flood
NORTH DAKOTA 4 1 21 0 16382000 Thunderstorm Wind
OHIO 1 0 5 0 16477050 Thunderstorm Wind
OKLAHOMA 67 2 94 19 31584000 Hail
OREGON 67 7 8 0 1289800 Flood
PENNSYLVANIA 5 8 17 28 57409950 Thunderstorm Wind
PUERTO RICO 22 0 10 0 7037050 Flash Flood
RHODE ISLAND 1 0 4 0 14800 Flash Flood
SOUTH CAROLINA 137 80 26 1 10173750 Thunderstorm Wind
SOUTH DAKOTA 2 4 13 1 589000 Thunderstorm Wind
ST LAWRENCE R 0 0 0 0 0 Marine Thunderstorm Wind
TENNESSEE 811 58 186 4 34068600 Flash Flood
TEXAS 649 17 97 55 57823050 Flash Flood
UTAH 13 3 17 4 2128500 Thunderstorm Wind
VERMONT 15 0 0 0 28213500 Flash Flood
VIRGIN ISLANDS 0 0 0 0 12000 Excessive Heat
VIRGINIA 15 1 11 0 20614210 Flash Flood
WASHINGTON 19 0 9 6 2286000 Heavy Snow
WEST VIRGINIA 658 0 2 1 10079000 Flood
WISCONSIN 9 1 2 5 13091000 Hail
WYOMING 1 0 2 0 1112000 High Wind

Table 1. This shows a summary of the key data points, sortable by state, including the numbers of deaths, injuries and amount of property damage in the last year as well as the most common Event Type in each state

The table allows planners to begin with actual figures for annual estimates with which to build annual budget and disaster preparation and response plans. Additionally, this table makes it easy for leaders to look up the numbers in neighboring states to identify if there may be inefficiencies that other states with similar climate threats have solved to reduce loss of life or property damage for similar events.

Conclusion and Recommendation

This project identified the most common weather events by frequency in the most recent 12-month window of available data (JUL 2024 - JUN 2025) as well as the highest casualty producing events (deaths and injuries) both during the event and secondary casualties associated with that event. Additionally, the events that cause the most property damage in terms of U.S. Dollars and in which months do these events occur combine to create an initial picture for officials and Emergency Managers to use to familiarize themselves with the threats in each state. Officials must be prepared for both the most likely events (highest frequency) and the most costly (human life, injuries and property damage) in their regions. To best prepare for these events, Emergency Managers and officials must budget available resources against each of these threats (people, training equipment), and source mutual aid agreements with other states for assistance as well as to assist their own neighbors. These agreements and preparation and response plans must be completed before the events occur to ensure efficient and effective use of resources to save lives and safeguard property. The data source may be studied in more details as needed by any interested party through additional comparisons, potentially zeroing in on a specific region of most interest.