In this document we will analyze data from the U.S. National Oceanic and Atmospheric Administration about different weather events and determine which kinds of weather events have the greatest impact on human health and the economy.
First, we read in the raw data file from NOAA.
storm <- read.csv("StormData.csv.bz2")
We consider first the types of events that are most harmful to human health.
We’re going to get a summary for fatalities and injuries for each event type. Our metric for damage to human life will be the sum of injuries and the figure of fatalities times 1000. It may not be possible to know how one can weigh a fatality versus an injury, but this allows us to account for some relative difference and allows us to combine damage to life into one number. This will be applied to each event. So first we will add a column to each row that contains this sum.
We’ll use dplyr to aid our data processing.
library(dplyr)
##
## 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
storm <- storm %>%
mutate(LIFEDMG = FATALITIES * 1000 + INJURIES, .after = INJURIES)
As there are multiple event types in the data that refer to similar events, we filter out event types with fewer than 100 observations to ensure that we get the aggregated event types. This should also give us a better sample size for each event type.
event_counts <- storm %>%
group_by(EVTYPE) %>%
count() %>%
filter(n >= 100)
events <- event_counts$EVTYPE
summary_lifedmg <- storm %>%
filter(EVTYPE %in% events) %>%
group_by(EVTYPE) %>%
summarise(MEAN_LIFEDMG = mean(LIFEDMG)) %>%
arrange(desc(MEAN_LIFEDMG))
For this analysis, we’ll further limit our groups to the top 5 for damage to life.
top_lifedmg <- summary_lifedmg %>%
top_n(5, MEAN_LIFEDMG) %>%
arrange(desc(MEAN_LIFEDMG))
print(top_lifedmg)
## # A tibble: 5 × 2
## EVTYPE MEAN_LIFEDMG
## <chr> <dbl>
## 1 HEAT 1224.
## 2 EXCESSIVE HEAT 1138.
## 3 RIP CURRENT 783.
## 4 RIP CURRENTS 672.
## 5 AVALANCHE 581.
We can see in the top 5 event types that there are a couple of pairs that could be combined, i.e. “HEAT” and “EXCESSIVE HEAT” and “RIP CURRENT” and “RIP CURRENTS”. We’ll go back to the original dataset and relabel all instances of “EXCESSIVE HEAT” as “HEAT” and all instances of “RIP CURRENTS” to “RIP CURRENT”.
storm <- storm %>%
mutate(EVTYPE = if_else(EVTYPE == "EXCESSIVE HEAT", "HEAT", EVTYPE)) %>%
mutate(EVTYPE = if_else(EVTYPE == "RIP CURRENTS", "RIP CURRENT", EVTYPE))
Now we’ll process again as we did before.
event_counts <- storm %>%
group_by(EVTYPE) %>%
count() %>%
filter(n >= 100)
events <- event_counts$EVTYPE
summary_lifedmg <- storm %>%
filter(EVTYPE %in% events) %>%
group_by(EVTYPE) %>%
summarise(MEAN_LIFEDMG = mean(LIFEDMG)) %>%
arrange(desc(MEAN_LIFEDMG))
And we recalculate the top 5 for each category.
top_lifedmg <- summary_lifedmg %>%
top_n(5, MEAN_LIFEDMG) %>%
arrange(desc(MEAN_LIFEDMG))
print(top_lifedmg)
## # A tibble: 5 × 2
## EVTYPE MEAN_LIFEDMG
## <chr> <dbl>
## 1 HEAT 1165.
## 2 RIP CURRENT 740.
## 3 AVALANCHE 581.
## 4 HURRICANE 351.
## 5 EXTREME COLD 245.
We’ll now consider the types of events that have the greatest economic consequences, as measured by damage to property and crops in the original data.
The data presents two columns for each category of economic damage, one for the value (PROPDMG, CROPDMG) and one for a multiplier (PROPDMGEXP, CROPDMGEXP). The multiplier indicates a factor to multiply the value by. For instance if PROPDMG is 25.0 and the PROPDMGEXP is “K” (meaning kilo or 1000), we would multiply 25.0 by 1000 to get $25,000 estimated property damage. So the first thing we’ll do is to create a new column with the expanded amount so that we can easily compare the data.
storm <- storm %>%
mutate(PROPDMG = PROPDMG * case_when(
PROPDMGEXP == "K" ~ 1000,
PROPDMGEXP == "M" ~ 1000000,
PROPDMGEXP == "B" ~ 1000000000,
.default = 1
)) %>%
mutate(CROPDMG = CROPDMG * case_when(
CROPDMGEXP == "K" ~ 1000,
CROPDMGEXP == "M" ~ 1000000,
CROPDMGEXP == "B" ~ 1000000000,
.default = 1
))
We’ll also create a new column that is the sum of PROPDMG and CROPDMG called ECONDMG.
storm <- storm %>%
mutate(ECONDMG = PROPDMG + CROPDMG, .after = CROPDMGEXP)
Now we’ll group by event type and get the top 5 for ECONDMG, much as we did for human health.
event_counts <- storm %>%
group_by(EVTYPE) %>%
count() %>%
filter(n >= 100)
events <- event_counts$EVTYPE
summary <- storm %>%
filter(EVTYPE %in% events) %>%
group_by(EVTYPE) %>%
summarise(MEAN_ECONDMG = mean(ECONDMG)) %>%
arrange(desc(MEAN_ECONDMG))
top_econdmg <- summary %>%
top_n(5, MEAN_ECONDMG) %>%
arrange(desc(MEAN_ECONDMG))
print(top_econdmg)
## # A tibble: 5 × 2
## EVTYPE MEAN_ECONDMG
## <chr> <dbl>
## 1 STORM SURGE 165990579.
## 2 HURRICANE 83966833.
## 3 RIVER FLOOD 58661298.
## 4 STORM SURGE/TIDE 31365122.
## 5 TROPICAL STORM 12148169.
The top 5 contains both “STORM SURGE” and STORM SURGE/TIDE”, so let’s group these two together under STORM STURGE by relabeling the corresponding rows in the original data frame.
storm <- storm %>%
mutate(EVTYPE = if_else(EVTYPE == "STORM SURGE/TIDE", "STORM SURGE", EVTYPE))
Now we’ll recalculate the summaries and top 5.
event_counts <- storm %>%
group_by(EVTYPE) %>%
count() %>%
filter(n >= 100)
events <- event_counts$EVTYPE
summary_econ <- storm %>%
filter(EVTYPE %in% events) %>%
group_by(EVTYPE) %>%
summarise(MEAN_ECONDMG = mean(ECONDMG)) %>%
arrange(desc(MEAN_ECONDMG))
top_econdmg <- summary_econ %>%
top_n(5, MEAN_ECONDMG) %>%
arrange(desc(MEAN_ECONDMG))
print(top_econdmg)
## # A tibble: 5 × 2
## EVTYPE MEAN_ECONDMG
## <chr> <dbl>
## 1 STORM SURGE 117275254.
## 2 HURRICANE 83966833.
## 3 RIVER FLOOD 58661298.
## 4 TROPICAL STORM 12148169.
## 5 DROUGHT 6036444.
For the purposes of this study, we define “harmful with respect to human health” as the sum of the fatalities * 1000 and injuries for a given event. Therefore we aggregated these over each event type and found that the following 5 events had the greatest recorded toll on human health:
print(top_lifedmg)
## # A tibble: 5 × 2
## EVTYPE MEAN_LIFEDMG
## <chr> <dbl>
## 1 HEAT 1165.
## 2 RIP CURRENT 740.
## 3 AVALANCHE 581.
## 4 HURRICANE 351.
## 5 EXTREME COLD 245.
par(mar = c(9, 5, 5, 2))
y <- top_lifedmg$MEAN_LIFEDMG
plt <- barplot(
main = "Mean damage to human life by event type",
y,
names.arg = top_lifedmg$EVTYPE,
las = 2,
ylab = "(fatalities x 1000) + injuries",
ylim = c(0, max(y) + 150)
)
text(x = plt, y = y + 70, labels = round(y, 1))
For the purposes of this study, we define “economic damage” as the sum of the property damage and crop damage for a given event. Therefore we aggregated these over each event type and found that the following 5 events had the greatest recorded economic damage:
print(top_econdmg)
## # A tibble: 5 × 2
## EVTYPE MEAN_ECONDMG
## <chr> <dbl>
## 1 STORM SURGE 117275254.
## 2 HURRICANE 83966833.
## 3 RIVER FLOOD 58661298.
## 4 TROPICAL STORM 12148169.
## 5 DROUGHT 6036444.
par(mar = c(9, 5, 5, 2))
y <- top_econdmg$MEAN_ECONDMG / 1000000
plt <- barplot(
main = "Mean economic damage by event type",
y,
names.arg = top_econdmg$EVTYPE,
las = 2,
ylab = "Millions of US dollars",
ylim = c(0, max(y) + 15)
)
text(x = plt, y = y + 10, labels = round(y, 1))