Synopsis

This report analyzes the NOAA Storm Database to identify which types of severe weather events are most harmful to population health and which have the greatest economic consequences across the United States. Using data from the raw CSV file, the study processes event types and their associated health impacts (injuries and fatalities) and economic damages (property and crop damages). Visualizations highlight the leading event types in each category, providing insights useful for municipal managers preparing for severe weather events.

Data Processing

# Load required packages
library(dplyr)
library(ggplot2)
library(readr)

# Load the raw NOAA Storm Database CSV file
storm_data <- read_csv("repdata_data_StormData.csv.bz2") 

# Preview data
head(storm_data)
## # A tibble: 6 × 37
##   STATE__ BGN_DATE   BGN_TIME TIME_ZONE COUNTY COUNTYNAME STATE EVTYPE BGN_RANGE
##     <dbl> <chr>      <chr>    <chr>      <dbl> <chr>      <chr> <chr>      <dbl>
## 1       1 4/18/1950… 0130     CST           97 MOBILE     AL    TORNA…         0
## 2       1 4/18/1950… 0145     CST            3 BALDWIN    AL    TORNA…         0
## 3       1 2/20/1951… 1600     CST           57 FAYETTE    AL    TORNA…         0
## 4       1 6/8/1951 … 0900     CST           89 MADISON    AL    TORNA…         0
## 5       1 11/15/195… 1500     CST           43 CULLMAN    AL    TORNA…         0
## 6       1 11/15/195… 2000     CST           77 LAUDERDALE AL    TORNA…         0
## # ℹ 28 more variables: BGN_AZI <chr>, BGN_LOCATI <chr>, END_DATE <chr>,
## #   END_TIME <chr>, COUNTY_END <dbl>, COUNTYENDN <lgl>, END_RANGE <dbl>,
## #   END_AZI <chr>, END_LOCATI <chr>, LENGTH <dbl>, WIDTH <dbl>, F <dbl>,
## #   MAG <dbl>, FATALITIES <dbl>, INJURIES <dbl>, PROPDMG <dbl>,
## #   PROPDMGEXP <chr>, CROPDMG <dbl>, CROPDMGEXP <chr>, WFO <chr>,
## #   STATEOFFIC <chr>, ZONENAMES <chr>, LATITUDE <dbl>, LONGITUDE <dbl>,
## #   LATITUDE_E <dbl>, LONGITUDE_ <dbl>, REMARKS <chr>, REFNUM <dbl>
# Select relevant columns for analysis
storm_data_sub <- storm_data %>%
  select(EVTYPE, FATALITIES, INJURIES, PROPDMG, PROPDMGEXP, CROPDMG, CROPDMGEXP)

# Standardize event types to uppercase
storm_data_sub$EVTYPE <- toupper(storm_data_sub$EVTYPE)

# Function to convert damage exponent codes to numeric multipliers
exp_to_num <- function(exp) {
  dplyr::case_when(
    exp %in% c("H","h") ~ 100,
    exp %in% c("K","k") ~ 1e3,
    exp %in% c("M","m") ~ 1e6,
    exp %in% c("B","b") ~ 1e9,
    TRUE ~ 1
  )
}

# Apply conversion for property and crop damages
storm_data_sub <- storm_data_sub %>%
  mutate(
    PROPDMGEXP = exp_to_num(PROPDMGEXP),
    CROPDMGEXP = exp_to_num(CROPDMGEXP),
    PROPDMG_TOTAL = PROPDMG * PROPDMGEXP,
    CROPDMG_TOTAL = CROPDMG * CROPDMGEXP,
    ECONOMIC_DAMAGE = PROPDMG_TOTAL + CROPDMG_TOTAL,
    HEALTH_IMPACT = FATALITIES + INJURIES
  )
# Summarize total health impact by event type
health_summary <- storm_data_sub %>%
  group_by(EVTYPE) %>%
  summarise(
    total_fatalities = sum(FATALITIES, na.rm=TRUE),
    total_injuries = sum(INJURIES, na.rm=TRUE),
    total_health_impact = sum(HEALTH_IMPACT, na.rm=TRUE)
  ) %>%
  arrange(desc(total_health_impact)) %>%
  filter(total_health_impact > 0) %>%
  slice(1:10) # top 10 event types

health_summary
## # A tibble: 10 × 4
##    EVTYPE            total_fatalities total_injuries total_health_impact
##    <chr>                        <dbl>          <dbl>               <dbl>
##  1 TORNADO                       5633          91346               96979
##  2 EXCESSIVE HEAT                1903           6525                8428
##  3 TSTM WIND                      504           6957                7461
##  4 FLOOD                          470           6789                7259
##  5 LIGHTNING                      816           5230                6046
##  6 HEAT                           937           2100                3037
##  7 FLASH FLOOD                    978           1777                2755
##  8 ICE STORM                       89           1975                2064
##  9 THUNDERSTORM WIND              133           1488                1621
## 10 WINTER STORM                   206           1321                1527
# Plot top 10 event types by total health impact
ggplot(health_summary, aes(x = reorder(EVTYPE, total_health_impact), y = total_health_impact)) +
  geom_bar(stat = "identity", fill = "tomato") +
  coord_flip() +
  labs(
    title = "Top 10 Severe Weather Event Types by Population Health Impact",
    x = "Event Type",
    y = "Total Fatalities and Injuries"
  )

# Summarize total economic damage by event type
economic_summary <- storm_data_sub %>%
  group_by(EVTYPE) %>%
  summarise(total_economic_damage = sum(ECONOMIC_DAMAGE, na.rm=TRUE)) %>%
  arrange(desc(total_economic_damage)) %>%
  filter(total_economic_damage > 0) %>%
  slice(1:10) # top 10 event types

economic_summary
## # A tibble: 10 × 2
##    EVTYPE            total_economic_damage
##    <chr>                             <dbl>
##  1 FLOOD                     150319678257 
##  2 HURRICANE/TYPHOON          71913712800 
##  3 TORNADO                    57352114049.
##  4 STORM SURGE                43323541000 
##  5 HAIL                       18758222016.
##  6 FLASH FLOOD                17562179167.
##  7 DROUGHT                    15018672000 
##  8 HURRICANE                  14610229010 
##  9 RIVER FLOOD                10148404500 
## 10 ICE STORM                   8967041360
# Plot top 10 event types by economic damage
ggplot(economic_summary, aes(x = reorder(EVTYPE, total_economic_damage), y = total_economic_damage / 1e9)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  coord_flip() +
  labs(
    title = "Top 10 Severe Weather Event Types by Economic Damage (Billions USD)",
    x = "Event Type",
    y = "Total Economic Damage (Billions USD)"
  )