This analysis examines the public-health and economic consequences of severe weather events recorded in the NOAA Storm Database. The analysis starts directly from the original compressed CSV file. Health consequences are measured using fatalities and injuries. Economic consequences are measured using property and crop damage. Damage values are converted to dollars using the exponent variables included in the database. The results identify the weather events associated with the greatest health and economic impacts in the United States.
The required R packages are loaded below.
knitr::opts_chunk$set(
echo = TRUE,
warning = FALSE,
message = FALSE,
fig.width = 9,
fig.height = 6
)
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.3.2
##
## 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(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.3.2
library(scales)
## Warning: package 'scales' was built under R version 4.4.0
The original compressed NOAA Storm Database file is loaded directly into R.
storm_raw <- read.csv(
"repdata_data_StormData.csv.bz2",
stringsAsFactors = FALSE
)
storm <- storm_raw %>%
select(
EVTYPE,
FATALITIES,
INJURIES,
PROPDMG,
PROPDMGEXP,
CROPDMG,
CROPDMGEXP
)
dim(storm)
## [1] 902297 7
Event names are standardized by converting them to uppercase and removing extra punctuation and spaces.
storm <- storm %>%
mutate(
EVENT_TYPE = toupper(trimws(EVTYPE)),
EVENT_TYPE = gsub("[^A-Z0-9/ ]", " ", EVENT_TYPE),
EVENT_TYPE = gsub("\\s+", " ", EVENT_TYPE),
EVENT_TYPE = trimws(EVENT_TYPE),
EVENT_TYPE = ifelse(EVENT_TYPE == "", "UNKNOWN", EVENT_TYPE)
)
Population-health consequences are calculated as the sum of fatalities and injuries.
health_summary <- storm %>%
group_by(EVENT_TYPE) %>%
summarise(
FATALITIES = sum(FATALITIES, na.rm = TRUE),
INJURIES = sum(INJURIES, na.rm = TRUE),
TOTAL_HARM = FATALITIES + INJURIES,
.groups = "drop"
) %>%
arrange(desc(TOTAL_HARM))
top_health <- health_summary %>%
slice_max(
order_by = TOTAL_HARM,
n = 10,
with_ties = FALSE
)
top_health
## # A tibble: 10 × 4
## EVENT_TYPE FATALITIES INJURIES TOTAL_HARM
## <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 817 5230 6047
## 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
The following function converts the damage exponent codes into monetary multipliers.
damage_multiplier <- function(exponent) {
exponent <- toupper(trimws(as.character(exponent)))
multiplier <- rep(NA_real_, length(exponent))
multiplier[exponent %in% c("", "0")] <- 1
multiplier[exponent == "H"] <- 1e2
multiplier[exponent == "K"] <- 1e3
multiplier[exponent == "M"] <- 1e6
multiplier[exponent == "B"] <- 1e9
numeric_exponent <- grepl("^[1-8]$", exponent)
multiplier[numeric_exponent] <-
10 ^ as.numeric(exponent[numeric_exponent])
multiplier
}
Property and crop damage are converted to dollars and combined.
storm <- storm %>%
mutate(
PROP_MULTIPLIER = damage_multiplier(PROPDMGEXP),
CROP_MULTIPLIER = damage_multiplier(CROPDMGEXP),
PROPERTY_DAMAGE = PROPDMG * PROP_MULTIPLIER,
CROP_DAMAGE = CROPDMG * CROP_MULTIPLIER
)
economic_summary <- storm %>%
group_by(EVENT_TYPE) %>%
summarise(
PROPERTY_DAMAGE = sum(PROPERTY_DAMAGE, na.rm = TRUE),
CROP_DAMAGE = sum(CROP_DAMAGE, na.rm = TRUE),
TOTAL_ECONOMIC_DAMAGE = PROPERTY_DAMAGE + CROP_DAMAGE,
.groups = "drop"
) %>%
arrange(desc(TOTAL_ECONOMIC_DAMAGE))
top_economic <- economic_summary %>%
slice_max(
order_by = TOTAL_ECONOMIC_DAMAGE,
n = 10,
with_ties = FALSE
)
top_economic
## # A tibble: 10 × 4
## EVENT_TYPE PROPERTY_DAMAGE CROP_DAMAGE TOTAL_ECONOMIC_DAMAGE
## <chr> <dbl> <dbl> <dbl>
## 1 FLOOD 144657709807 5661968450 150319678257
## 2 HURRICANE/TYPHOON 69305840000 2607872800 71913712800
## 3 TORNADO 56947380616. 414953270 57362333886.
## 4 STORM SURGE 43323536000 5000 43323541000
## 5 HAIL 15735267513. 3025954473 18761221986.
## 6 FLASH FLOOD 16822723978. 1421317100 18244041078.
## 7 DROUGHT 1046106000 13972566000 15018672000
## 8 HURRICANE 11868319010 2741910000 14610229010
## 9 RIVER FLOOD 5118945500 5029459000 10148404500
## 10 ICE STORM 3944927860 5022113500 8967041360
The following table shows the ten event types with the largest combined number of fatalities and injuries.
knitr::kable(
top_health,
format.args = list(big.mark = ","),
col.names = c(
"Event type",
"Fatalities",
"Injuries",
"Total fatalities and injuries"
),
caption = "Ten weather events with the greatest population-health consequences."
)
| Event type | Fatalities | Injuries | Total fatalities and injuries |
|---|---|---|---|
| TORNADO | 5,633 | 91,346 | 96,979 |
| EXCESSIVE HEAT | 1,903 | 6,525 | 8,428 |
| TSTM WIND | 504 | 6,957 | 7,461 |
| FLOOD | 470 | 6,789 | 7,259 |
| LIGHTNING | 817 | 5,230 | 6,047 |
| HEAT | 937 | 2,100 | 3,037 |
| FLASH FLOOD | 978 | 1,777 | 2,755 |
| ICE STORM | 89 | 1,975 | 2,064 |
| THUNDERSTORM WIND | 133 | 1,488 | 1,621 |
| WINTER STORM | 206 | 1,321 | 1,527 |
ggplot(
top_health,
aes(
x = reorder(EVENT_TYPE, TOTAL_HARM),
y = TOTAL_HARM
)
) +
geom_col(fill = "#B22222") +
coord_flip() +
scale_y_continuous(labels = comma) +
labs(
title = "Weather Events Most Harmful to Population Health",
subtitle = "Combined fatalities and injuries",
x = "Weather event",
y = "Total fatalities and injuries"
) +
theme_minimal(base_size = 12)
Figure 1. Ten weather event categories with the greatest combined number of fatalities and injuries.
The event type with the greatest population-health impact was TORNADO, with a combined total of 96,979 fatalities and injuries.
The following table shows the ten event types with the greatest combined property and crop damage.
economic_table <- top_economic %>%
mutate(
PROPERTY_DAMAGE_BILLIONS = PROPERTY_DAMAGE / 1e9,
CROP_DAMAGE_BILLIONS = CROP_DAMAGE / 1e9,
TOTAL_DAMAGE_BILLIONS = TOTAL_ECONOMIC_DAMAGE / 1e9
) %>%
select(
EVENT_TYPE,
PROPERTY_DAMAGE_BILLIONS,
CROP_DAMAGE_BILLIONS,
TOTAL_DAMAGE_BILLIONS
)
knitr::kable(
economic_table,
digits = 2,
col.names = c(
"Event type",
"Property damage ($ billions)",
"Crop damage ($ billions)",
"Total damage ($ billions)"
),
caption = "Ten weather events with the greatest economic consequences."
)
| Event type | Property damage ($ billions) | Crop damage ($ billions) | Total damage ($ billions) |
|---|---|---|---|
| FLOOD | 144.66 | 5.66 | 150.32 |
| HURRICANE/TYPHOON | 69.31 | 2.61 | 71.91 |
| TORNADO | 56.95 | 0.41 | 57.36 |
| STORM SURGE | 43.32 | 0.00 | 43.32 |
| HAIL | 15.74 | 3.03 | 18.76 |
| FLASH FLOOD | 16.82 | 1.42 | 18.24 |
| DROUGHT | 1.05 | 13.97 | 15.02 |
| HURRICANE | 11.87 | 2.74 | 14.61 |
| RIVER FLOOD | 5.12 | 5.03 | 10.15 |
| ICE STORM | 3.94 | 5.02 | 8.97 |
ggplot(
top_economic,
aes(
x = reorder(EVENT_TYPE, TOTAL_ECONOMIC_DAMAGE),
y = TOTAL_ECONOMIC_DAMAGE / 1e9
)
) +
geom_col(fill = "#1F5A94") +
coord_flip() +
scale_y_continuous(
labels = label_number(
accuracy = 1,
big.mark = ","
)
) +
labs(
title = "Weather Events with the Greatest Economic Consequences",
subtitle = "Combined property and crop damage",
x = "Weather event",
y = "Economic damage ($ billions)"
) +
theme_minimal(base_size = 12)
Figure 2. Ten weather event categories with the greatest combined property and crop damage.
The event type with the greatest economic impact was FLOOD, with approximately $150 billion in combined property and crop damage.
The NOAA Storm Database indicates that TORNADO caused the greatest overall harm to population health, while FLOOD caused the greatest economic damage. These findings show that public-health consequences and economic consequences should be evaluated separately when preparing for severe weather events.