Economic and Health Impacts of Severe Weather Events in the US

Synopsis

In this report, we explore the U.S. National Oceanic and Atmospheric Administration’s (NOAA) Storm Database, which contains data from 1950 to 2011, to try to understand which major weather events in the United States have the greatest economic and population health impacts. The data is transformed to include only the necessary variables and to gather multiple variables into one. Then, we analyze the number of fatalities and injuries by event type and show which have had the most harmful consequences. Finally, we analyze the amount of property and crop damage by event type and which events have been most impactful for the economy. The greatest population health impacts are caused disproportionately by tornadoes, while the greatest economic impact is caused by hail and floods.

Data Processing

Loading necessary libraries

library(ggplot2)
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.1.3
## 
## 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(tidyr)
## Warning: package 'tidyr' was built under R version 4.1.3

Loading and inspecting the data

In this step, we load the dataset from the file located in our current directory and we examine its properties with the str() function.

stormdata <- read.csv("repdata_data_StormData.csv.bz2")
str(stormdata)
## '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 ...

Here, we can identify the variables that are of interest to us: * EVTYPE that describes the type of weather event * FATALITIES & INJURIES that describe the population health impacts of the events * PROPDMG, PROPDMGEXP, CROPDMG & CROPDMGEXP that describe the economic impacts of the events

Subsetting the data

We will select the variables discussed above to make the dataset smaller and more manageable.

library(dplyr)
stormdatas <- stormdata %>%
  select(c("EVTYPE", "FATALITIES", "INJURIES",
           "PROPDMG", "PROPDMGEXP", "CROPDMG", "CROPDMGEXP"))

Combining variables for graphing

Next, we must combine the variables of PROPDMG & PROPDMGEXP, as well as CROPDMG & CROPDMGEXP, to represent the damage in a single number and thus facilitate graphing. The following chunk creates 2 new variables that get filled according to the one-letter codes in PROPDMGEXP and CROPDMGEXP:

  • property: PROPDMG values multiplied by 1,000, 1,000,000 or 1,000,000,000 according to the corresponding exponent value (K, M or B)
  • crop: CROPDMG values multiplied by 1,000, 1,000,000 or 1,000,000,000 according to the corresponding exponent value (K, M or B)

It also eliminates the four previous columns from the dataset since they are no longer necessary.

storm_order <- stormdatas %>%
  mutate(property = ifelse(PROPDMGEXP == "K", PROPDMG * 1000, PROPDMG)) %>%
  mutate(property = ifelse(PROPDMGEXP == "M", PROPDMG * 1000000, property)) %>%
  mutate(property = ifelse(PROPDMGEXP == "B", PROPDMG * 1000000000, property)) %>%
  mutate(crop = ifelse(CROPDMGEXP == "K", CROPDMG * 1000, CROPDMG)) %>%
  mutate(crop = ifelse(CROPDMGEXP == "K", CROPDMG * 1000000, crop)) %>%
  mutate(crop = ifelse(CROPDMGEXP == "K", CROPDMG * 1000000000, crop)) %>%
  select(-c(PROPDMG, PROPDMGEXP, CROPDMG, CROPDMGEXP))

Now that we have our ordered dataset, we can move on to analyzing it.

Results

Which types of events are most harmful with respect to population health?

First, let’s take a look of the distribution of data for fatalities and injuries.

summary(storm_order$FATALITIES)
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##   0.0000   0.0000   0.0000   0.0168   0.0000 583.0000
summary(storm_order$INJURIES)
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
##    0.0000    0.0000    0.0000    0.1557    0.0000 1700.0000

We can see that both fatalities and injuries reach high numbers (158 deaths and 1700 injuries), but that about 75% of the weather events have low counts of both and that the means are both below 1. This would seem to indicate that there are a few outlier events that lead to massive public health consequences but that this is not often the case.

Let’s summarize the total fatalities and injuries by event type.

health_type <- storm_order %>%
  group_by(EVTYPE) %>%
  summarize(Fatalities = sum(FATALITIES), Injuries = sum(INJURIES), total = sum(Fatalities) + sum(Injuries)) %>%
gather("Type_consequence", "Count", 2:3) %>%
  arrange(desc(total))
  

print(health_type)
## # A tibble: 1,970 x 4
##    EVTYPE         total Type_consequence Count
##    <chr>          <dbl> <chr>            <dbl>
##  1 TORNADO        96979 Fatalities        5633
##  2 TORNADO        96979 Injuries         91346
##  3 EXCESSIVE HEAT  8428 Fatalities        1903
##  4 EXCESSIVE HEAT  8428 Injuries          6525
##  5 TSTM WIND       7461 Fatalities         504
##  6 TSTM WIND       7461 Injuries          6957
##  7 FLOOD           7259 Fatalities         470
##  8 FLOOD           7259 Injuries          6789
##  9 LIGHTNING       6046 Fatalities         816
## 10 LIGHTNING       6046 Injuries          5230
## # i 1,960 more rows

Finally, let’s plot the top 10 severe weather events with the highest number of population health consequences, showing their total fatalities and injuries. We must do this because plotting the whole dataset would result in a very difficult to interpret graph.

ggplot(health_type[1:20,], aes(x=reorder(EVTYPE, -Count), y=Count)) + 
  geom_bar(stat="identity", position="dodge", aes(fill=Type_consequence)) +
  labs(x="Type of weather event", title="Severe Weather Events with the Greatest Population Health Consequences", fill="Type of health consequence") +
  theme(axis.text.x = element_text(angle = 45,hjust = 1))

In the plot, we can see that the most impactful weather event are tornadoes, with a much higher number of fatalities and injuries than the rest of events. The following events that affect public health the most are excessive heat, thunderstorm winds, floods and lighting. It’s important to allocate resources to prevent and reduce the damage caused by tornadoes, as well as the other weather events shown in the graph.

Which types of events have the greatest economic consequences?

First, let’s take a look of the distribution of data for crop and property damage.

summary(storm_order$property)
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## 0.000e+00 0.000e+00 0.000e+00 4.735e+05 5.000e+02 1.150e+11
summary(storm_order$crop)
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## 0.000e+00 0.000e+00 0.000e+00 1.488e+09 0.000e+00 9.900e+11

We can see that both property and crop damage reach enormous numbers (on the billions range) and that the means are also very high. However, it seems about 75% of the events recorded showed no economic damage, which means the high numbers must be due to a few very costful events. Let’s find out which ones!

Let’s summarize the total fatalities and injuries by event type.

economic_type <- storm_order %>%
  group_by(EVTYPE) %>%
  summarize(Property_Damage = sum(property), Crop_Damage = sum(crop), total = sum(property) + sum(crop)) %>%
gather("Type_damage", "Count", 2:3) %>%
  arrange(desc(total))


print(economic_type)
## # A tibble: 1,970 x 4
##    EVTYPE        total Type_damage       Count
##    <chr>         <dbl> <chr>             <dbl>
##  1 HAIL        5.77e14 Property_Damage 1.57e10
##  2 HAIL        5.77e14 Crop_Damage     5.77e14
##  3 FLASH FLOOD 1.78e14 Property_Damage 1.61e10
##  4 FLASH FLOOD 1.78e14 Crop_Damage     1.78e14
##  5 FLOOD       1.63e14 Property_Damage 1.45e11
##  6 FLOOD       1.63e14 Crop_Damage     1.63e14
##  7 TSTM WIND   1.09e14 Property_Damage 4.48e 9
##  8 TSTM WIND   1.09e14 Crop_Damage     1.09e14
##  9 TORNADO     9.96e13 Property_Damage 5.69e10
## 10 TORNADO     9.96e13 Crop_Damage     9.95e13
## # i 1,960 more rows

Finally, let’s plot the top 10 severe weather events with the highest economic consequence, showing their total property damage and crop damage. We must do this because plotting the whole dataset would result in a very difficult to interpret graph. Furthermore, we must use a logarithmic scale to plot the dollars lost since crop damage is on a much larger scale than property damage.

ggplot(economic_type[1:20,], aes(x=reorder(EVTYPE, -Count), y=Count/1e8)) + geom_bar(stat="identity", position="dodge", aes(fill=Type_damage)) +
  scale_y_continuous(trans='log10') +
  labs(x="Type of weather event", title="Severe Weather Events with the Greatest Economic Consequences", fill="Type of damage", y="Hundreds of millions (US Dollars)") +
  theme(axis.text.x = element_text(angle = 45,hjust = 1)) 

Here, we can see that the greatest economic impact on crops is caused by the events of hail, flash floods and floods. However, the greatest property damage is caused floods and tornadoes. It’s important to take specific actions to protect and restore both crops and property damaged by weather events.