Synopsis

This report analyzes the health and economic impact of severe weather events in the United States. The data used in this analysis is from the U.S. National Oceanic and Atmospheric Administration’s (NOAA) storm database. The data contains information on the number of injuries and fatalities, and the property and crop damage caused by severe weather events. The analysis focuses on the most harmful events with respect to population health and the events with the greatest economic consequences.

Data Processing

Download and read the data. Only read the data if already downloaded.

url <- "https://d396qusza40orc.cloudfront.net/repdata%2Fdata%2FStormData.csv.bz2"

if (!file.exists("data.csv.bz2")) {
  download.file(url, "data.csv.bz2")
}

data <- read.table("data.csv.bz2", sep=",", header=TRUE)

Now we briefly examine the data.

str(data)
## 'data.frame':    902297 obs. of  37 variables:
##  $ STATE__   : num  1 1 1 1 1 1 1 1 1 1 ...
##  $ BGN_DATE  : chr  "4/18/1950 0:00:00" "4/18/1950 0:00:00" "2/20/1951 0:00:00" "6/8/1951 0:00:00" ...
##  $ BGN_TIME  : chr  "0130" "0145" "1600" "0900" ...
##  $ TIME_ZONE : chr  "CST" "CST" "CST" "CST" ...
##  $ COUNTY    : num  97 3 57 89 43 77 9 123 125 57 ...
##  $ COUNTYNAME: chr  "MOBILE" "BALDWIN" "FAYETTE" "MADISON" ...
##  $ STATE     : chr  "AL" "AL" "AL" "AL" ...
##  $ EVTYPE    : chr  "TORNADO" "TORNADO" "TORNADO" "TORNADO" ...
##  $ BGN_RANGE : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ BGN_AZI   : chr  "" "" "" "" ...
##  $ BGN_LOCATI: chr  "" "" "" "" ...
##  $ END_DATE  : chr  "" "" "" "" ...
##  $ END_TIME  : chr  "" "" "" "" ...
##  $ COUNTY_END: num  0 0 0 0 0 0 0 0 0 0 ...
##  $ COUNTYENDN: logi  NA NA NA NA NA NA ...
##  $ END_RANGE : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ END_AZI   : chr  "" "" "" "" ...
##  $ END_LOCATI: chr  "" "" "" "" ...
##  $ LENGTH    : num  14 2 0.1 0 0 1.5 1.5 0 3.3 2.3 ...
##  $ WIDTH     : num  100 150 123 100 150 177 33 33 100 100 ...
##  $ F         : int  3 2 2 2 2 2 2 1 3 3 ...
##  $ MAG       : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ 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  "" "" "" "" ...
##  $ WFO       : chr  "" "" "" "" ...
##  $ STATEOFFIC: chr  "" "" "" "" ...
##  $ ZONENAMES : chr  "" "" "" "" ...
##  $ LATITUDE  : num  3040 3042 3340 3458 3412 ...
##  $ LONGITUDE : num  8812 8755 8742 8626 8642 ...
##  $ LATITUDE_E: num  3051 0 0 0 0 ...
##  $ LONGITUDE_: num  8806 0 0 0 0 ...
##  $ REMARKS   : chr  "" "" "" "" ...
##  $ REFNUM    : num  1 2 3 4 5 6 7 8 9 10 ...

Subsetting relevant values and columns

We are only interested in the number of injuries and fatalities, and the event type. The health variables are: FATALITIES and INJURIES. The economic variables are: PROPDMG and CROPDMG. The Events are in the column EVTYPE.

subset <- c("FATALITIES", "INJURIES", "PROPDMG", "CROPDMG",
            "PROPDMGEXP", "CROPDMGEXP", "EVTYPE")
data <- data[, subset]

See the tail of the subsetted data.

tail(data)
##        FATALITIES INJURIES PROPDMG CROPDMG PROPDMGEXP CROPDMGEXP         EVTYPE
## 902292          0        0       0       0          K          K WINTER WEATHER
## 902293          0        0       0       0          K          K      HIGH WIND
## 902294          0        0       0       0          K          K      HIGH WIND
## 902295          0        0       0       0          K          K      HIGH WIND
## 902296          0        0       0       0          K          K       BLIZZARD
## 902297          0        0       0       0          K          K     HEAVY SNOW

See the 10 most frequent event types.

sort(table(data$EVTYPE), decreasing=TRUE)[1:10]
## 
##               HAIL          TSTM WIND  THUNDERSTORM WIND            TORNADO 
##             288661             219940              82563              60652 
##        FLASH FLOOD              FLOOD THUNDERSTORM WINDS          HIGH WIND 
##              54277              25326              20843              20212 
##          LIGHTNING         HEAVY SNOW 
##              15754              15708

Transforming the data

We can combine all event type which contain WIND as one event type. We can do the same for FLOOD, HAIL, and TORNADO. Lets add another event OTHER for the rest of the events. Lets do this in a new column called EVENT

data$EVENT <- "OTHER"
data$EVENT[grep("WIND", data$EVTYPE, ignore.case = TRUE)] <- "WIND"
data$EVENT[grep("FLOOD", data$EVTYPE, ignore.case = TRUE)] <- "FLOOD"
data$EVENT[grep("HAIL", data$EVTYPE, ignore.case = TRUE)] <- "HAIL"
data$EVENT[grep("TORNADO", data$EVTYPE, ignore.case = TRUE)] <- "TORNADO"
data$EVENT[grep("HEAT", data$EVTYPE, ignore.case = TRUE)] <- "HEAT"
data$EVENT[grep("STORM", data$EVTYPE, ignore.case = TRUE)] <- "STORM"
data$EVENT[grep("RAIN", data$EVTYPE, ignore.case = TRUE)] <- "RAIN"
data$EVENT[grep("SNOW", data$EVTYPE, ignore.case = TRUE)] <- "SNOW"
data$EVENT[grep("WINTER", data$EVTYPE, ignore.case = TRUE)] <- "WINTER"

Show the 10 most frequent events

sort(table(data$EVENT), decreasing=TRUE)[1:10]
## 
##    HAIL    WIND   STORM   FLOOD TORNADO   OTHER  WINTER    SNOW    RAIN    HEAT 
##  290306  254323  113156   82689   60700   48970   19604   17701   12200    2648

Now we check the property damage and crop damage exponent columns.

sort(table(data$PROPDMGEXP), decreasing=TRUE)[1:10]
## 
##             K      M      0      B      5      1      2      ?      m 
## 465934 424665  11330    216     40     28     25     13      8      7
sort(table(data$CROPDMGEXP), decreasing=TRUE)[1:10]
## 
##             K      M      k      0      B      ?      2      m   <NA> 
## 618413 281832   1994     21     19      9      7      1      1

We need to convert the exponent to a number. We will convert the following letters to numbers: - B -> 9 (Billion) - H -> 2 (Hundred) - K -> 3 (Thousand) - M -> 6 (Million) - ? -> 0 (Unknown) Everything else will be converted to the corresponding integer. Ex: “1” to 1.

data$PROPDMGEXP <- as.character(data$PROPDMGEXP)
data$PROPDMGEXP[data$PROPDMGEXP == ""] <- "0"
data$PROPDMGEXP[data$PROPDMGEXP == "+"] <- "1"
data$PROPDMGEXP[data$PROPDMGEXP == "-"] <- "-1"
data$PROPDMGEXP[toupper(data$PROPDMGEXP) == "B"] <- "9"
data$PROPDMGEXP[toupper(data$PROPDMGEXP) == "H"] <- "2"
data$PROPDMGEXP[toupper(data$PROPDMGEXP) == "K"] <- "3"
data$PROPDMGEXP[toupper(data$PROPDMGEXP) == "M"] <- "6"
data$PROPDMGEXP[data$PROPDMGEXP == "?"] <- "0"
data$PROPDMGEXP <- as.numeric(data$PROPDMGEXP)

Now we do the same for the crop damage exponent.

data$CROPDMGEXP <- as.character(data$CROPDMGEXP)
data$CROPDMGEXP[data$CROPDMGEXP == ""] <- "0"
data$CROPDMGEXP[data$CROPDMGEXP == "+"] <- "1"
data$CROPDMGEXP[data$CROPDMGEXP == "-"] <- "-1"
data$CROPDMGEXP[toupper(data$CROPDMGEXP) == "B"] <- "9"
data$CROPDMGEXP[toupper(data$CROPDMGEXP) == "H"] <- "2"
data$CROPDMGEXP[toupper(data$CROPDMGEXP) == "K"] <- "3"
data$CROPDMGEXP[toupper(data$CROPDMGEXP) == "M"] <- "6"
data$CROPDMGEXP[data$CROPDMGEXP == "?"] <- "0"
data$CROPDMGEXP <- as.numeric(data$CROPDMGEXP)

Now we can calculate the total property and crop damage.

data$PROPDMG <- data$PROPDMG * 10^data$PROPDMGEXP
data$CROPDMG <- data$CROPDMG * 10^data$CROPDMGEXP

Analysis

Aggregating Health Data

We can aggregate the health data by event type.

health <- aggregate(data[, c("FATALITIES", "INJURIES")], by=list(data$EVENT), FUN=sum, na.rm=TRUE)
colnames(health) <- c("EVENT", "FATALITIES", "INJURIES")
health
##      EVENT FATALITIES INJURIES
## 1    FLOOD       1524     8602
## 2     HAIL         20     1466
## 3     HEAT       3138     9224
## 4    OTHER       2626    12224
## 5     RAIN        109      303
## 6     SNOW        169     1166
## 7    STORM        416     5339
## 8  TORNADO       5661    91407
## 9     WIND       1204     8906
## 10  WINTER        278     1891

Aggregating Economic Data

We can aggregate the economic data by event type.

economic <- aggregate(data[, c("PROPDMG", "CROPDMG")], by=list(data$EVENT), FUN=sum)
colnames(economic) <- c("EVENT", "PROPDMG", "CROPDMG")
economic
##      EVENT      PROPDMG     CROPDMG
## 1    FLOOD 168189669013 12266906100
## 2     HAIL  15780900013  3111583873
## 3     HEAT     20325750   904469280
## 4    OTHER  97248432320 23588880870
## 5     RAIN   3262050210   919315800
## 6     SNOW   1032519750   134683100
## 7    STORM  66513048615  6374474888
## 8  TORNADO  58603318467   417461520
## 9     WIND  10797310420  1338972750
## 10  WINTER   6777295251    47444000

Results

Across the United States, which types of events are most harmful with respect to population health?

library(tidyr)
library(ggplot2)
health <- gather(health, key = type, value = Count, FATALITIES, INJURIES)
ggplot(health, aes(x=EVENT, y=Count, fill=type)) +
  geom_bar(stat="identity", position="dodge") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(title="Health Impact by Event Type", x="Event Type", y="Count")

From the plot we can see that Tornados are the most harmful event type with respect to population health.

Across the United States, which types of events have the greatest economic consequences?

economic <- gather(economic, key = type, value = Count, PROPDMG, CROPDMG)
ggplot(economic, aes(x=EVENT, y=Count/10^6, fill=type)) +
  geom_bar(stat="identity", position="dodge") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(title="Economic Impact by Event Type", x="Event Type", y="Damage in Millions of Dollars")

From the plot we can see that floods have the greatest economic damage.

Conclusion

Tornados are the most harmful event type with respect to population health, while floods have the greatest economic consequences. This analysis can help policymakers and emergency responders to better prepare for and respond to severe weather events in the United States.