Synopsis

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.

Data Processing

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

Results

Events most harmful to population health

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."
)
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.

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.

Events with the greatest economic consequences

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."
)
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.

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.

Conclusion

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.