Synopsis

This report looks at NOAA’s storm database (1950 - Nov 2011) to figure out which weather events hurt people the most and which cost the most money. Health impact is measured as fatalities + injuries per event type, and economic impact as property + crop damage in dollars. Turns out tornadoes are by far the most dangerous to people, way ahead of everything else, while floods cause the most economic damage, with hurricanes/typhoons and tornadoes not far behind.

Data Processing

The raw data is a csv file compressed with bzip2, downloaded from the course site. R can read .bz2 files directly with read.csv, so there’s no preprocessing done outside this doc.

knitr::opts_chunk$set(echo = TRUE)
suppressPackageStartupMessages(library(dplyr))
library(ggplot2)
dataFile <- "repdata_data_StormData.csv.bz2"
storm <- read.csv(bzfile(dataFile), stringsAsFactors = FALSE, fileEncoding = "latin1")
dim(storm)
## [1] 902297     37

We only need a few of the 37 columns here: the event type (EVTYPE), the health columns (FATALITIES, INJURIES), and the damage columns (PROPDMG, PROPDMGEXP, CROPDMG, CROPDMGEXP).

storm <- storm %>%
    select(EVTYPE, FATALITIES, INJURIES, PROPDMG, PROPDMGEXP, CROPDMG, CROPDMGEXP)

Cleaning up EVTYPE

EVTYPE is pretty messy - different capitalization, extra spaces, typos everywhere. Just trimming whitespace and uppercasing it fixes a good chunk of the duplicates (e.g. "tstm wind" and "TSTM WIND" become the same thing).

storm$EVTYPE <- trimws(toupper(storm$EVTYPE))

Turning damage codes into actual dollars

Damage amounts are split into a number (PROPDMG, CROPDMG) and an exponent code (PROPDMGEXP, CROPDMGEXP) - "K" for thousand, "M" for million, "B" for billion, digits for powers of 10. Anything else (blank, weird symbol, whatever) is treated as x1, since those cases are rare and don’t move the total much.

expToMultiplier <- function(exp) {
    exp <- toupper(trimws(exp))
    mult <- rep(1, length(exp))
    mult[exp == "H"] <- 1e2
    mult[exp == "K"] <- 1e3
    mult[exp == "M"] <- 1e6
    mult[exp == "B"] <- 1e9
    numericCodes <- grepl("^[0-8]$", exp)
    mult[numericCodes] <- 10^as.numeric(exp[numericCodes])
    mult
}

storm <- storm %>%
    mutate(
        propDamage = PROPDMG * expToMultiplier(PROPDMGEXP),
        cropDamage = CROPDMG * expToMultiplier(CROPDMGEXP),
        totalDamage = propDamage + cropDamage,
        totalHealth = FATALITIES + INJURIES
    )

Grouping by event type

Now we sum up fatalities, injuries and damage by event type and grab the top 10 for each.

healthByEvent <- storm %>%
    group_by(EVTYPE) %>%
    summarise(fatalities = sum(FATALITIES), injuries = sum(INJURIES),
              totalHealth = sum(totalHealth)) %>%
    arrange(desc(totalHealth))

economicByEvent <- storm %>%
    group_by(EVTYPE) %>%
    summarise(propDamage = sum(propDamage), cropDamage = sum(cropDamage),
              totalDamage = sum(totalDamage)) %>%
    arrange(desc(totalDamage))

topHealth <- head(healthByEvent, 10)
topEconomic <- head(economicByEvent, 10)

Results

Which events are worst for public health?

Top 10 event types ranked by fatalities + injuries combined.

topHealth
## # A tibble: 10 × 4
##    EVTYPE            fatalities injuries totalHealth
##    <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                816     5230        6046
##  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
topHealth$EVTYPE <- factor(topHealth$EVTYPE, levels = rev(topHealth$EVTYPE))

ggplot(topHealth, aes(x = EVTYPE, y = totalHealth)) +
    geom_col(fill = "firebrick") +
    coord_flip() +
    labs(title = "Top 10 Event Types by Total Fatalities and Injuries (1950-2011)",
         x = "Event Type", y = "Total Fatalities + Injuries") +
    theme_minimal()

Figure 1. Fatalities + injuries for the top 10 event types, US, 1950-2011. Tornadoes are way out in front of everything else here.

Which events cost the most money?

Top 10 event types by property + crop damage, in billions of dollars.

topEconomic %>%
    mutate(propDamage = propDamage / 1e9, cropDamage = cropDamage / 1e9,
           totalDamage = totalDamage / 1e9)
## # A tibble: 10 × 4
##    EVTYPE            propDamage cropDamage totalDamage
##    <chr>                  <dbl>      <dbl>       <dbl>
##  1 FLOOD                 145.     5.66          150.  
##  2 HURRICANE/TYPHOON      69.3    2.61           71.9 
##  3 TORNADO                56.9    0.415          57.4 
##  4 STORM SURGE            43.3    0.000005       43.3 
##  5 HAIL                   15.7    3.03           18.8 
##  6 FLASH FLOOD            16.8    1.42           18.2 
##  7 DROUGHT                 1.05  14.0            15.0 
##  8 HURRICANE              11.9    2.74           14.6 
##  9 RIVER FLOOD             5.12   5.03           10.1 
## 10 ICE STORM               3.94   5.02            8.97
topEconomic$EVTYPE <- factor(topEconomic$EVTYPE, levels = rev(topEconomic$EVTYPE))

ggplot(topEconomic, aes(x = EVTYPE, y = totalDamage / 1e9)) +
    geom_col(fill = "steelblue") +
    coord_flip() +
    labs(title = "Top 10 Event Types by Total Economic Damage (1950-2011)",
         x = "Event Type", y = "Total Property + Crop Damage (Billion USD)") +
    theme_minimal()

Figure 2. Property + crop damage (billions USD) for the top 10 event types, US, 1950-2011. Floods lead, with hurricanes/typhoons and tornadoes close behind.

Conclusion

So overall: tornadoes are the biggest threat to people, by a wide margin, and floods do the most economic damage, with hurricanes/typhoons and tornadoes also up there. Hopefully this helps whoever’s deciding where to put resources for storm prep.