This report analyzes the public health and economic impacts of severe weather events across the United States using data from the NOAA Storm Database spanning from 1950 to November 2011. The objective is to identify which weather events cause the most harm to human population health and which yield the most severe economic consequences. Population health impact is measured by aggregating the total number of fatalities and injuries across different event types. Economic consequences are determined by calculating the combined financial damage to properties and crops after normalizing character-based exponent multipliers. The analysis reveals that tornadoes are overwhelmingly the most hazardous events to public health, while flash floods and river floods incur the highest overall economic costs. These insights can help municipal managers and emergency planners prioritize resources and update infrastructure risk assessments effectively.
To begin the analysis, we configure the global options to ensure all
R code chunks remain visible (echo = TRUE) for full
reproducibility. We also load the necessary libraries for data
processing and visual plotting. The script checks for the presence of
the compressed raw data file in the working directory; if it is missing,
it downloads it directly from the source repository.
library(dplyr)
library(ggplot2)
library(tidyr)
# Ensure all code chunks are rendered in the final document
knitr::opts_chunk$set(echo = TRUE, cache = TRUE)
# File paths and source configuration
url <- "https://d396qusza40orc.cloudfront.net/repdata%2Fdata%2FStormData.csv.bz2"
destfile <- "StormData.csv.bz2"
# Download the file if it doesn't already exist locally
if (!file.exists(destfile)) {
download.file(url, destfile, method = "curl")
}
# Read the compressed CSV dataset
raw_data <- read.csv(destfile)
health_data <- raw_data %>%
select(EVTYPE, FATALITIES, INJURIES) %>%
group_by(EVTYPE) %>%
summarize(
Total_Fatalities = sum(FATALITIES, na.rm = TRUE),
Total_Injuries = sum(INJURIES, na.rm = TRUE),
Total_Health_Impact = sum(FATALITIES + INJURIES, na.rm = TRUE)
) %>%
arrange(desc(Total_Health_Impact)) %>%
slice_head(n = 10)
# Function to transform exponential codes into their absolute numerical value
convert_exponent <- function(exp_char) {
exp_char <- toupper(as.character(exp_char))
ifelse(exp_char == "K", 1000,
ifelse(exp_char == "M", 1000000,
ifelse(exp_char == "B", 1000000000,
ifelse(exp_char %in% c("", "-", "?", "+"), 1,
ifelse(exp_char %in% as.character(0:8), 10,
ifelse(exp_char == "H", 100, 1))))))
}
# Apply mapping and compute final absolute financial figures
economic_data <- raw_data %>%
select(EVTYPE, PROPDMG, PROPDMGEXP, CROPDMG, CROPDMGEXP) %>%
mutate(
Property_Multiplier = convert_exponent(PROPDMGEXP),
Crop_Multiplier = convert_exponent(CROPDMGEXP),
Calculated_Property_Damage = PROPDMG * Property_Multiplier,
Calculated_Crop_Damage = CROPDMG * Crop_Multiplier,
Combined_Financial_Damage = Calculated_Property_Damage + Calculated_Crop_Damage
) %>%
group_by(EVTYPE) %>%
summarize(
Property_Total = sum(Calculated_Property_Damage, na.rm = TRUE),
Crop_Total = sum(Calculated_Crop_Damage, na.rm = TRUE),
Total_Economic_Damage = sum(Combined_Financial_Damage, na.rm = TRUE)
) %>%
arrange(desc(Total_Economic_Damage)) %>%
slice_head(n = 10)
# Pivot the table to a long format to generate a stacked bar chart
health_long <- health_data %>%
pivot_longer(cols = c(Total_Fatalities, Total_Injuries),
names_to = "Casualty_Type",
values_to = "Count") %>%
mutate(Casualty_Type = gsub("Total_", "", Casualty_Type))
ggplot(health_long, aes(x = reorder(EVTYPE, -Count), y = Count, fill = Casualty_Type)) +
geom_bar(stat = "identity") +
labs(
title = "Top 10 Most Harmful Severe Weather Events to US Population Health",
x = "Weather Event Type",
y = "Total Aggregated Casualties",
fill = "Casualty Type"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
ggplot(economic_data, aes(x = reorder(EVTYPE, -Total_Economic_Damage), y = Total_Economic_Damage / 1e9)) +
geom_bar(stat = "identity", fill = "darkgreen") +
labs(
title = "Top 10 Severe Weather Events with Highest Economic Cost",
x = "Weather Event Type",
y = "Total Financial Loss (in Billions of USD)"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))