if (!file.exists("repdata_data_StormData.csv.bz2")) {
stop("repdata_data_StormData.csv not found in the working directory. ",
"Download it from https://d396qusza40orc.cloudfront.net/repdata%2Fdata%2FStormData.csv.bz2 ",
"and place it (unzipped, if needed) next to this .Rmd file.")
}
storm <- fread("repdata_data_StormData.csv.bz2", na.strings = "")
dim(storm)
## [1] 902297 37
storm <- storm[, .(EVTYPE, FATALITIES, INJURIES, PROPDMG, PROPDMGEXP, CROPDMG, CROPDMGEXP)]
str(storm)
## Classes 'data.table' and 'data.frame': 902297 obs. of 7 variables:
## $ EVTYPE : chr "TORNADO" "TORNADO" "TORNADO" "TORNADO" ...
## $ FATALITIES: num 0 0 0 0 0 0 0 0 1 0 ...
## $ INJURIES : num 15 0 2 2 2 6 1 0 14 0 ...
## $ PROPDMG : num 25 2.5 25 2.5 2.5 2.5 2.5 2.5 25 25 ...
## $ PROPDMGEXP: chr "K" "K" "K" "K" ...
## $ CROPDMG : num 0 0 0 0 0 0 0 0 0 0 ...
## $ CROPDMGEXP: chr NA NA NA NA ...
## - attr(*, ".internal.selfref")=<externalptr>
Cleaning EVTYPE.
storm[, EVTYPE := toupper(trimws(EVTYPE))]
uniqueN(storm$EVTYPE)
## [1] 890
Converting damage magnitude codes.
PROPDMG/CROPDMG give a raw number, and
PROPDMGEXP/CROPDMGEXP give a code for its
order of magnitude (K = thousands, M =
millions, B = billions, per the NWS documentation; a small
number of rows use other symbols such as digits, H,
-, +, or are blank – for those the
documentation is ambiguous or the encoding is a known data entry
artifact, so we conservatively treat them as contributing 0 damage
rather than guess). We convert both fields into an actual dollar figure
and combine them into a single total-damage column.
expToMultiplier <- function(x) {
x <- toupper(trimws(x))
out <- rep(0, length(x))
out[x == "K"] <- 1e3
out[x == "M"] <- 1e6
out[x == "B"] <- 1e9
out[x == "H"] <- 1e2
digit_idx <- grepl("^[0-8]$", x)
out[digit_idx] <- 10 ^ as.numeric(x[digit_idx])
out
}
storm[, propDamage := PROPDMG * expToMultiplier(PROPDMGEXP)]
storm[, cropDamage := CROPDMG * expToMultiplier(CROPDMGEXP)]
storm[, totalDamage := propDamage + cropDamage]
storm[, healthImpact := FATALITIES + INJURIES]
Finally, we aggregate by event type for the two questions this report answers: total health impact (fatalities + injuries), and total economic impact (property + crop damage).
healthByEvent <- storm[, .(Fatalities = sum(FATALITIES),
Injuries = sum(INJURIES),
Total = sum(healthImpact)), by = EVTYPE]
healthByEvent <- healthByEvent[order(-Total)]
econByEvent <- storm[, .(PropertyDamage = sum(propDamage),
CropDamage = sum(cropDamage),
Total = sum(totalDamage)), by = EVTYPE]
econByEvent <- econByEvent[order(-Total)]
top10health <- head(healthByEvent, 10)
top10econ <- head(econByEvent, 10)
top10health
## EVTYPE Fatalities Injuries Total
## <char> <num> <num> <num>
## 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
health_long <- data.table::melt(top10health[, .(EVTYPE, Fatalities, Injuries)],
id.vars = "EVTYPE")
ggplot(health_long, aes(x = reorder(EVTYPE, -value), y = value, fill = variable)) +
geom_bar(stat = "identity", position = "dodge") +
labs(title = "Figure 1: Top 10 Event Types by Impact on Population Health",
x = "Event Type", y = "Total Count (1950-2011)", fill = NULL) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Figure 1 shows the ten event types with the highest combined number of fatalities and injuries, split out by fatalities vs. injuries. Tornadoes are responsible for substantially more injuries than any other event type, and are also among the leading causes of fatalities, making them the single most harmful event category to population health overall.
top10econ
## EVTYPE PropertyDamage CropDamage Total
## <char> <num> <num> <num>
## 1: FLOOD 144657709800 5661968450 150319678250
## 2: HURRICANE/TYPHOON 69305840000 2607872800 71913712800
## 3: TORNADO 56947380614 414953270 57362333884
## 4: STORM SURGE 43323536000 5000 43323541000
## 5: HAIL 15735267456 3025954470 18761221926
## 6: FLASH FLOOD 16822723772 1421317100 18244040872
## 7: DROUGHT 1046106000 13972566000 15018672000
## 8: HURRICANE 11868319010 2741910000 14610229010
## 9: RIVER FLOOD 5118945500 5029459000 10148404500
## 10: ICE STORM 3944927860 5022113500 8967041360
econ_long <- data.table::melt(top10econ[, .(EVTYPE, PropertyDamage, CropDamage)],
id.vars = "EVTYPE")
ggplot(econ_long, aes(x = reorder(EVTYPE, -value), y = value / 1e9, fill = variable)) +
geom_bar(stat = "identity", position = "dodge") +
labs(title = "Figure 2: Top 10 Event Types by Economic Damage",
x = "Event Type", y = "Total Damage (Billions USD, 1950-2011)", fill = NULL) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Figure 2 shows the ten event types with the highest combined property and crop damage, split out by damage type. Property damage dominates crop damage for almost every top event type. The events with the largest total economic impact are dominated by large-scale, wide-area events (floods and hurricanes/typhoons), which cause extensive property damage over large regions, in contrast to population-health impact, which is dominated by short-duration, high-frequency events like tornadoes.