This report analyzes the U.S. National Oceanic and Atmospheric Administration’s (NOAA) Storm Database to identify which types of severe weather events are most harmful to population health and which have the greatest economic consequences. The database covers events recorded between 1950 and November 2011. To assess public health impact, total fatalities and total injuries were aggregated by event type. To assess economic impact, property and crop damage estimates were converted from their raw magnitude codes (e.g. “K”, “M”, “B”) into dollar figures and summed by event type. Across the full record, tornadoes are responsible for by far the largest number of fatalities and injuries of any event type, making them the leading public health threat in this dataset. Floods and hurricanes/typhoons are responsible for the largest total economic damage, driven primarily by property damage, while droughts stand out as the leading cause of crop damage specifically. These findings suggest that resources for both emergency preparedness and economic mitigation planning should be weighted heavily toward tornado readiness and flood/hurricane protection.
The analysis begins from the original, compressed CSV file provided by the course. If the file is not already present in the working directory, it is downloaded here directly.
data_url <- "https://d396qusza40orc.cloudfront.net/repdata%2Fdata%2FStormData.csv.bz2"
data_file <- "StormData.csv.bz2"
if (!file.exists(data_file)) {
download.file(data_url, destfile = data_file, mode = "wb", quiet = TRUE)
}
The compressed CSV is read directly with read.csv(), which can decompress .bz2 files natively via a bzfile() connection.
storm_raw <- read.csv(bzfile(data_file), stringsAsFactors = FALSE)
dim(storm_raw)
## [1] 902297 37
Only the columns needed to answer the two questions are kept: the event type, the health-impact variables (FATALITIES, INJURIES), and the economic-impact variables (PROPDMG, PROPDMGEXP, CROPDMG, CROPDMGEXP).
library(dplyr)
storm <- storm_raw %>%
select(EVTYPE, FATALITIES, INJURIES, PROPDMG, PROPDMGEXP, CROPDMG, CROPDMGEXP)
EVTYPE contains many inconsistent labels (extra whitespace, mixed case, and some near-duplicate spellings). Whitespace is trimmed and labels are converted to uppercase so that, for example, "tornado", "Tornado", and "TORNADO " are treated as the same event type. This is a light-touch cleaning step; no attempt is made to merge every near-duplicate free-text variant, since doing so would require an extensive manual lookup table beyond the scope of this report, and the dominant categories (tornado, flood, wind, heat, etc.) are unaffected by this limitation.
storm$EVTYPE <- trimws(toupper(storm$EVTYPE))
PROPDMGEXP and CROPDMGEXP store a multiplier code alongside the numeric PROPDMG/CROPDMG values: "K"/"k" = thousands, "M"/"m" = millions, "B"/"b" = billions, and digit characters represent powers of ten. Any other or blank code is treated as a multiplier of 1 (i.e., no scaling), following the NOAA documentation’s description of these fields as the source of the intended scale.
exp_to_multiplier <- function(code) {
code <- toupper(trimws(code))
case_when(
code == "K" ~ 1e3,
code == "M" ~ 1e6,
code == "B" ~ 1e9,
code %in% as.character(0:9) ~ 10^as.numeric(code),
TRUE ~ 1
)
}
storm <- storm %>%
mutate(
prop_dollars = PROPDMG * exp_to_multiplier(PROPDMGEXP),
crop_dollars = CROPDMG * exp_to_multiplier(CROPDMGEXP),
total_econ_dollars = prop_dollars + crop_dollars
)
For each cleaned event type, total fatalities, total injuries, total property damage, total crop damage, and combined economic damage are summed across all recorded events.
by_event <- storm %>%
group_by(EVTYPE) %>%
summarise(
total_fatalities = sum(FATALITIES, na.rm = TRUE),
total_injuries = sum(INJURIES, na.rm = TRUE),
total_health = total_fatalities + total_injuries,
total_prop = sum(prop_dollars, na.rm = TRUE),
total_crop = sum(crop_dollars, na.rm = TRUE),
total_econ = sum(total_econ_dollars, na.rm = TRUE),
.groups = "drop"
)
The top 10 event types by combined fatalities and injuries are shown below.
top_health <- by_event %>%
arrange(desc(total_health)) %>%
slice_head(n = 10)
top_health
## # A tibble: 10 x 7
## EVTYPE total_fatalities total_injuries total_health total_prop total_crop
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 TORNA… 5633 91346 96979 5.69e10 414953270
## 2 EXCES… 1903 6525 8428 7.75e 6 492402000
## 3 TSTM … 504 6957 7461 4.49e 9 554007350
## 4 FLOOD 470 6789 7259 1.45e11 5661968450
## 5 LIGHT… 816 5230 6046 9.30e 8 12092090
## 6 HEAT 937 2100 3037 1.80e 6 401461500
## 7 FLASH… 978 1777 2755 1.68e10 1421317100
## 8 ICE S… 89 1975 2064 3.94e 9 5022113500
## 9 THUND… 133 1488 1621 3.48e 9 414843050
## 10 WINTE… 206 1321 1527 6.69e 9 26944000
## # … with 1 more variable: total_econ <dbl>
library(ggplot2)
library(tidyr)
health_long <- top_health %>%
select(EVTYPE, total_fatalities, total_injuries) %>%
pivot_longer(
cols = c(total_fatalities, total_injuries),
names_to = "measure",
values_to = "count"
) %>%
mutate(
measure = recode(measure,
total_fatalities = "Fatalities",
total_injuries = "Injuries"
),
EVTYPE = factor(EVTYPE, levels = rev(top_health$EVTYPE))
)
ggplot(health_long, aes(x = EVTYPE, y = count, fill = measure)) +
geom_col(position = "dodge") +
coord_flip() +
scale_fill_manual(values = c("Fatalities" = "#b5652d", "Injuries" = "#d7bfa6")) +
labs(
title = "Top 10 Event Types by Public Health Impact",
x = "Event type",
y = "Total count (1950-2011)",
fill = NULL
) +
theme_minimal(base_size = 12)
Figure 1. Total fatalities and total injuries by event type, for the ten event types with the highest combined health impact, 1950-2011.
Figure 1 shows total fatalities (dark bars) and total injuries (light bars) for the ten event types with the greatest combined health impact. TORNADO accounts for the largest combined total, with 5,633 fatalities and 91,346 injuries recorded across the period.
The top 10 event types by combined property and crop damage are shown below, with dollar totals expressed in billions for readability.
top_econ <- by_event %>%
arrange(desc(total_econ)) %>%
slice_head(n = 10) %>%
mutate(
prop_billion = total_prop / 1e9,
crop_billion = total_crop / 1e9
)
top_econ %>% select(EVTYPE, prop_billion, crop_billion, total_econ)
## # A tibble: 10 x 4
## EVTYPE prop_billion crop_billion total_econ
## <chr> <dbl> <dbl> <dbl>
## 1 FLOOD 145. 5.66 150319678257
## 2 HURRICANE/TYPHOON 69.3 2.61 71913712800
## 3 TORNADO 56.9 0.415 57362333946.
## 4 STORM SURGE 43.3 0.000005 43323541000
## 5 HAIL 15.7 3.03 18761221491.
## 6 FLASH FLOOD 16.8 1.42 18244041078.
## 7 DROUGHT 1.05 14.0 15018672000
## 8 HURRICANE 11.9 2.74 14610229010
## 9 RIVER FLOOD 5.12 5.03 10148404500
## 10 ICE STORM 3.94 5.02 8967041360
econ_long <- top_econ %>%
select(EVTYPE, prop_billion, crop_billion) %>%
pivot_longer(
cols = c(prop_billion, crop_billion),
names_to = "measure",
values_to = "billions"
) %>%
mutate(
measure = recode(measure,
prop_billion = "Property damage",
crop_billion = "Crop damage"
),
EVTYPE = factor(EVTYPE, levels = rev(top_econ$EVTYPE))
)
ggplot(econ_long, aes(x = EVTYPE, y = billions, fill = measure)) +
geom_col(position = "stack") +
coord_flip() +
scale_fill_manual(values = c("Property damage" = "#3c2a21", "Crop damage" = "#b5652d")) +
labs(
title = "Top 10 Event Types by Economic Impact",
x = "Event type",
y = "Total damage (billions of dollars, 1950-2011)",
fill = NULL
) +
theme_minimal(base_size = 12)
Figure 2. Total property and crop damage (in billions of dollars) by event type, for the ten event types with the highest combined economic impact, 1950-2011.
Figure 2 shows total property damage (dark segment) and crop damage (light segment), stacked to show combined economic impact, for the ten costliest event types. FLOOD produced the largest combined economic damage, at approximately $150.3 billion. Separately, examining crop damage alone shows that DROUGHT is responsible for the single largest crop damage total, reflecting its disproportionate effect on agriculture relative to structural property.
Tornadoes represent the clearest public health risk in the NOAA Storm Database, both in terms of fatalities and injuries, far outpacing any other event type. Economically, water-related events — floods and hurricanes/typhoons — cause the greatest combined damage, primarily through property destruction, while drought stands out specifically as the dominant driver of crop losses. These patterns suggest that public health preparedness resources should prioritize tornado warning systems and shelter infrastructure, while economic mitigation planning (e.g., flood defenses and insurance policy) should prioritize flood- and hurricane-prone regions.
Analysis generated automatically with R version 4.0.0 (2020-04-24) on July 27, 2026.