This analysis examines severe weather events across the United States using NOAA storm data. It identifies the event types associated with the greatest harm to human health, measured by fatalities and injuries, and the greatest economic consequences, measured by property and crop damage.
The original NOAA storm database is provided as a compressed CSV file. The following code downloads the raw dataset if it is not already available and loads it into R.
# Download the original NOAA dataset if needed
if (!file.exists("StormData.csv.bz2")) {
download.file(
"https://d396qusza40orc.cloudfront.net/repdata%2Fdata%2FStormData.csv.bz2",
destfile = "StormData.csv.bz2",
mode = "wb"
)
}
# Load the raw compressed CSV file
storm <- read.csv(
bzfile("StormData.csv.bz2"),
stringsAsFactors = FALSE
)
# Inspect the dataset
dim(storm)
## [1] 902297 37
names(storm)
## [1] "STATE__" "BGN_DATE" "BGN_TIME" "TIME_ZONE" "COUNTY"
## [6] "COUNTYNAME" "STATE" "EVTYPE" "BGN_RANGE" "BGN_AZI"
## [11] "BGN_LOCATI" "END_DATE" "END_TIME" "COUNTY_END" "COUNTYENDN"
## [16] "END_RANGE" "END_AZI" "END_LOCATI" "LENGTH" "WIDTH"
## [21] "F" "MAG" "FATALITIES" "INJURIES" "PROPDMG"
## [26] "PROPDMGEXP" "CROPDMG" "CROPDMGEXP" "WFO" "STATEOFFIC"
## [31] "ZONENAMES" "LATITUDE" "LONGITUDE" "LATITUDE_E" "LONGITUDE_"
## [36] "REMARKS" "REFNUM"
head(storm)
## STATE__ BGN_DATE BGN_TIME TIME_ZONE COUNTY COUNTYNAME STATE EVTYPE
## 1 1 4/18/1950 0:00:00 0130 CST 97 MOBILE AL TORNADO
## 2 1 4/18/1950 0:00:00 0145 CST 3 BALDWIN AL TORNADO
## 3 1 2/20/1951 0:00:00 1600 CST 57 FAYETTE AL TORNADO
## 4 1 6/8/1951 0:00:00 0900 CST 89 MADISON AL TORNADO
## 5 1 11/15/1951 0:00:00 1500 CST 43 CULLMAN AL TORNADO
## 6 1 11/15/1951 0:00:00 2000 CST 77 LAUDERDALE AL TORNADO
## BGN_RANGE BGN_AZI BGN_LOCATI END_DATE END_TIME COUNTY_END COUNTYENDN
## 1 0 0 NA
## 2 0 0 NA
## 3 0 0 NA
## 4 0 0 NA
## 5 0 0 NA
## 6 0 0 NA
## END_RANGE END_AZI END_LOCATI LENGTH WIDTH F MAG FATALITIES INJURIES PROPDMG
## 1 0 14.0 100 3 0 0 15 25.0
## 2 0 2.0 150 2 0 0 0 2.5
## 3 0 0.1 123 2 0 0 2 25.0
## 4 0 0.0 100 2 0 0 2 2.5
## 5 0 0.0 150 2 0 0 2 2.5
## 6 0 1.5 177 2 0 0 6 2.5
## PROPDMGEXP CROPDMG CROPDMGEXP WFO STATEOFFIC ZONENAMES LATITUDE LONGITUDE
## 1 K 0 3040 8812
## 2 K 0 3042 8755
## 3 K 0 3340 8742
## 4 K 0 3458 8626
## 5 K 0 3412 8642
## 6 K 0 3450 8748
## LATITUDE_E LONGITUDE_ REMARKS REFNUM
## 1 3051 8806 1
## 2 0 0 2
## 3 0 0 3
## 4 0 0 4
## 5 0 0 5
## 6 0 0 6
The analysis measures population health impacts using fatalities and injuries. Economic impacts are estimated using property and crop damage. The original damage values are multiplied by their respective magnitude factors to estimate total losses in dollars.
# Convert event types to uppercase for consistent grouping
storm$EVTYPE <- toupper(trimws(storm$EVTYPE))
# Convert damage magnitude codes into dollar multipliers
damage_multiplier <- function(x) {
x <- toupper(as.character(x))
result <- rep(NA_real_, length(x))
result[x == ""] <- 1
result[x == "H"] <- 100
result[x == "K"] <- 1000
result[x == "M"] <- 1000000
result[x == "B"] <- 1000000000
result[x %in% as.character(0:8)] <-
10 ^ as.numeric(x[x %in% as.character(0:8)])
result
}
# Estimate property and crop damage in dollars
storm$PROPDMG_USD <- storm$PROPDMG *
ifelse(is.na(damage_multiplier(storm$PROPDMGEXP)), 0,
damage_multiplier(storm$PROPDMGEXP))
storm$CROPDMG_USD <- storm$CROPDMG *
ifelse(is.na(damage_multiplier(storm$CROPDMGEXP)), 0,
damage_multiplier(storm$CROPDMGEXP))
# Replace missing damage and health values with zero
for (v in c("FATALITIES", "INJURIES", "PROPDMG_USD", "CROPDMG_USD")) {
storm[[v]][is.na(storm[[v]])] <- 0
}
# Aggregate population health impacts by event type
health <- aggregate(
cbind(FATALITIES, INJURIES) ~ EVTYPE,
data = storm,
FUN = sum
)
health$total_health_impact <- health$FATALITIES + health$INJURIES
health <- health[order(-health$total_health_impact), ]
# Aggregate economic impacts by event type
economic <- aggregate(
cbind(PROPDMG_USD, CROPDMG_USD) ~ EVTYPE,
data = storm,
FUN = sum
)
economic$total_damage <- economic$PROPDMG_USD + economic$CROPDMG_USD
economic <- economic[order(-economic$total_damage), ]
# Display the top 10 event types
head(health, 10)
## EVTYPE FATALITIES INJURIES total_health_impact
## 750 TORNADO 5633 91346 96979
## 108 EXCESSIVE HEAT 1903 6525 8428
## 771 TSTM WIND 504 6957 7461
## 146 FLOOD 470 6789 7259
## 410 LIGHTNING 816 5230 6046
## 235 HEAT 937 2100 3037
## 130 FLASH FLOOD 978 1777 2755
## 379 ICE STORM 89 1975 2064
## 677 THUNDERSTORM WIND 133 1488 1621
## 880 WINTER STORM 206 1321 1527
head(economic, 10)
## EVTYPE PROPDMG_USD CROPDMG_USD total_damage
## 146 FLOOD 144657709807 5661968450 150319678257
## 364 HURRICANE/TYPHOON 69305840000 2607872800 71913712800
## 750 TORNADO 56947380616 414953270 57362333886
## 591 STORM SURGE 43323536000 5000 43323541000
## 204 HAIL 15735267513 3025954473 18761221986
## 130 FLASH FLOOD 16822723978 1421317100 18244041078
## 76 DROUGHT 1046106000 13972566000 15018672000
## 355 HURRICANE 11868319010 2741910000 14610229010
## 521 RIVER FLOOD 5118945500 5029459000 10148404500
## 379 ICE STORM 3944927860 5022113500 8967041360
The following figure shows the ten event types with the highest combined fatalities and injuries across the United States.
top_health <- head(health, 10)
par(mar = c(5, 12, 4, 2))
barplot(
rev(top_health$total_health_impact),
names.arg = rev(top_health$EVTYPE),
horiz = TRUE,
las = 1,
col = "tomato",
main = "Top 10 Events by Population Health Impact",
xlab = "Combined Fatalities and Injuries"
)
The following figure shows the ten event types with the highest estimated combined property and crop damage.
top_economic <- head(economic, 10)
par(mar = c(5, 12, 4, 2))
barplot(
rev(top_economic$total_damage) / 1e9,
names.arg = rev(top_economic$EVTYPE),
horiz = TRUE,
las = 1,
col = "steelblue",
main = "Top 10 Events by Economic Damage",
xlab = "Estimated Property and Crop Damage (Billions of USD)"
)
The results identify which event types have the largest recorded impacts on human health and economic losses. These summaries can help decision-makers understand which severe weather events account for the greatest recorded burdens in the NOAA database.