Synopsis

Given that the analysis will be read by a government or municipal manager who might be
responsible for preparing for severe weather events and will need to prioritize resources for different
types of events This analysis, we:

  1. focus on the last 3 years worth of data. We consider the last 3 years
    worth of data relevant to making these types of decisions.

  2. produce a report of fatalities and injuries by state and county
    where there were at least 5 fatalities or at least 50 injuries

The source data contains many columns, but we only require a small subset, which will help with performance
in generating the report.

The last 3 years worth of data are also the cleanest data, requiring very little transformations. It contains
47 discrete events (all upper case) and the following exponential multipliers:
- K = Thousands-> 1,000
- M = Millions -> 1,000,000
- B = Billions -> 1,000,000,000

Data Processing

Data Processing which describes (in words and code) how the data were loaded into R and processed for analysis. In particular, your analysis must start from the raw CSV file containing the data. You cannot do any preprocessing outside the document. If preprocessing is time-consuming you may consider using the cache = TRUE cache = TRUE option for certain code chunks.

if (system.file(package="R.utils") == "")
{install.packages("R.utils")}

if (system.file(package="lubridate") == "")
{install.packages("lubridate")}

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
library(ggplot2)
library(lubridate)
## Warning: package 'lubridate' was built under R version 4.2.3
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
library(scales)
library(R.utils)
## Warning: package 'R.utils' was built under R version 4.2.3
## Loading required package: R.oo
## Loading required package: R.methodsS3
## R.methodsS3 v1.8.2 (2022-06-13 22:00:14 UTC) successfully loaded. See ?R.methodsS3 for help.
## R.oo v1.25.0 (2022-06-12 02:20:02 UTC) successfully loaded. See ?R.oo for help.
## 
## Attaching package: 'R.oo'
## The following object is masked from 'package:R.methodsS3':
## 
##     throw
## The following objects are masked from 'package:methods':
## 
##     getClasses, getMethods
## The following objects are masked from 'package:base':
## 
##     attach, detach, load, save
## R.utils v2.12.2 (2022-11-11 22:00:03 UTC) successfully loaded. See ?R.utils for help.
## 
## Attaching package: 'R.utils'
## The following object is masked from 'package:utils':
## 
##     timestamp
## The following objects are masked from 'package:base':
## 
##     cat, commandArgs, getOption, isOpen, nullfile, parse, warnings
# load in the data from the website
tempsd <- tempfile()
download.file("https://d396qusza40orc.cloudfront.net/repdata%2Fdata%2FStormData.csv.bz2",tempsd, mode="wb")
bunzip2(tempsd,"stormdata.csv", overwrite=TRUE)
unlink(tempsd)

sdDF <- read.csv("stormdata.csv", header=TRUE)

sdDF <- sdDF %>%
  select(state=STATE, county=COUNTYNAME, BGN_DATE, eventType=EVTYPE, FATALITIES, INJURIES, PROPDMG, PROPDMGEXP, CROPDMG, CROPDMGEXP)

# Add a year column to make it easier to filter and get max year
sdDF <- sdDF %>%
  mutate(year = year(mdy_hms(BGN_DATE)))

# Many variations of events, but we only care about events after 2008 for this analysis, so there are only 47 distinct events
# from that point forward as per unique() query below.
unique((filter(sdDF,year>2008))$eventType)
##  [1] "FLOOD"                    "STRONG WIND"             
##  [3] "BLIZZARD"                 "WINTER STORM"            
##  [5] "HEAVY SNOW"               "THUNDERSTORM WIND"       
##  [7] "WINTER WEATHER"           "FLASH FLOOD"             
##  [9] "HEAVY RAIN"               "LAKE-EFFECT SNOW"        
## [11] "COLD/WIND CHILL"          "HIGH WIND"               
## [13] "DENSE FOG"                "HAIL"                    
## [15] "EXTREME COLD/WIND CHILL"  "TORNADO"                 
## [17] "WILDFIRE"                 "FUNNEL CLOUD"            
## [19] "LANDSLIDE"                "MARINE THUNDERSTORM WIND"
## [21] "COASTAL FLOOD"            "ICE STORM"               
## [23] "FROST/FREEZE"             "LIGHTNING"               
## [25] "MARINE STRONG WIND"       "ASTRONOMICAL LOW TIDE"   
## [27] "SLEET"                    "WATERSPOUT"              
## [29] "DUST STORM"               "FREEZING FOG"            
## [31] "DROUGHT"                  "AVALANCHE"               
## [33] "HIGH SURF"                "DUST DEVIL"              
## [35] "RIP CURRENT"              "HEAT"                    
## [37] "MARINE HAIL"              "MARINE HIGH WIND"        
## [39] "EXCESSIVE HEAT"           "STORM SURGE/TIDE"        
## [41] "DENSE SMOKE"              "TROPICAL DEPRESSION"     
## [43] "TROPICAL STORM"           "TSUNAMI"                 
## [45] "HURRICANE"                "SEICHE"                  
## [47] "LAKESHORE FLOOD"
# get the year that we want to filter to be greater than or equal to (last 3 years)
ThreeYearsAgo = max(sdDF[["year"]]) - 3
sdDF <- filter(sdDF,year>ThreeYearsAgo)

# str(sdDF)
# 
# # what are the unique crop and property damage exponential values?
# # (a) crop
# unique(sdDF$CROPDMGEXP)
# # "K" "M" "B"
# 
# unique(sdDF$PROPDMGEXP)
# # "K" "M" "B" "0"

# # Looking at PROPDMGEXP = 0, we see only 1 row of data all zeroed out so we can ignore it 
# # or treat it as a 0 multiplier.
# filter(sdDF,PROPDMGEXP=="0")
# # state county          BGN_DATE   eventType FATALITIES INJURIES PROPDMG PROPDMGEXP CROPDMG CROPDMGEXP year
# # 1    MI   KENT 7/27/2011 0:00:00 FLASH FLOOD          0        0       0          0       0          K 2011

#
# 1. Across the United States, which types of events (as indicated in the 
# EVTYPE variable) are most harmful with respect to population health?
#
sdByEVTYPEDF<- group_by(sdDF, eventType)
sdByEVTYPEByFIDF <- summarize(sdByEVTYPEDF, total_fatalities=sum(FATALITIES), total_injuries=sum(INJURIES))
sdByEVTYPEByFIDFTop10 <- 
  head(arrange(sdByEVTYPEByFIDF,
               desc(total_fatalities),
               desc(total_injuries)),10)

# Determine the years to show in the plots
timeFrame <- paste(ThreeYearsAgo,'-',ThreeYearsAgo + 3)

#
# Consider writing your report as if it were to be read by a government or municipal manager who might be 
# responsible for preparing for severe weather events and will need to prioritize resources for different 
# types of events. However, there is no need to make any specific recommendations in your report.
#
# I interpret this as producing a report of fatalities and injuries in recent history (last 3 years)
# by state and county where there were at least 5 fatalities or at least 50 injuries
#
sdByEVTYPEDetailsDF<- group_by(sdDF, state, county, eventType)
sdByEVTYPEByFIDetailsDF <- summarize(sdByEVTYPEDetailsDF, Fatalities=sum(FATALITIES), Injuries=sum(INJURIES))
## `summarise()` has grouped output by 'state', 'county'. You can override using
## the `.groups` argument.
sdByEVTYPEByFIDetailsDF <- 
  arrange(filter(sdByEVTYPEByFIDetailsDF,Fatalities>5 | Injuries>50),state, county, eventType)


#
# 2. Across the United States, which types of events have the greatest economic consequences?
# I interpret 'greatest economic consequences' as combined property damage and crop damage.
# 

# add a columns to just put in the actual numeric multiplier for both property and crop damage:
# K = Thousands-> 1,000
# M = Millions -> 1,000,000
# B = Billions -> 1,000,000,000

# create a function for this
applyMultiplier <- function(MultType){
  case_when(MultType == 'K' ~ 1000
            ,MultType == 'M' ~ 1000000
            ,MultType == 'B' ~ 1000000000
            ,TRUE ~ 0
  )
}

# add column that calculates all damage
sdDF <- sdDF %>%
  mutate(allDamage = PROPDMG * applyMultiplier(PROPDMGEXP) + 
           CROPDMG * applyMultiplier(CROPDMGEXP))

# # Verify that  the new values look correct
# sdDF %>%
#   filter(PROPDMGEXP == 'M')

sdDmgByEVTYPEDF<- group_by(sdDF, eventType)
sdDmgByEVTYPEByCPDF <- summarize(sdDmgByEVTYPEDF, total_damage=sum(allDamage))
sdDmgByEVTYPEByCPDFTop10 <- 
  head(arrange(sdDmgByEVTYPEByCPDF,
               desc(total_damage)),10)

Results

# show table by state and county with significant recent (i.e., last 3 years) fatalities/injuries 
# for government to act upon/make decisions from
knitr::kable(sdByEVTYPEByFIDetailsDF, caption = "FIGURE 1: Report for government officials to use for resource prioritization. Ordered by state and county.")
FIGURE 1: Report for government officials to use for resource prioritization. Ordered by state and county.
state county eventType Fatalities Injuries
AL CALHOUN TORNADO 9 26
AL DEKALB TORNADO 28 28
AL ELMORE TORNADO 6 20
AL FRANKLIN TORNADO 27 0
AL HALE TORNADO 6 40
AL JACKSON TORNADO 8 0
AL JEFFERSON TORNADO 20 720
AL LAWRENCE TORNADO 14 0
AL MADISON TORNADO 9 1
AL MARION TORNADO 25 200
AL MARSHALL TORNADO 6 89
AL ST. CLAIR TORNADO 13 35
AL TUSCALOOSA TORNADO 44 800
AL WALKER TORNADO 9 60
AR BENTON FLASH FLOOD 6 0
AR MONTGOMERY FLASH FLOOD 20 24
AS PSZ002 TSUNAMI 32 129
CA CAZ505 HIGH SURF 8 0
FL FLZ168 RIP CURRENT 9 17
GA CATOOSA TORNADO 8 30
GA DOUGLAS FLASH FLOOD 6 0
ID ADA THUNDERSTORM WIND 0 70
IL ILZ014 COLD/WIND CHILL 20 0
IL ILZ014 HEAT 22 0
IN MARION THUNDERSTORM WIND 7 43
LA LAZ002 EXCESSIVE HEAT 8 0
MA HAMPDEN TORNADO 6 400
MI MIZ077 RIP CURRENT 7 4
MO JASPER TORNADO 158 1150
MO MOZ090 EXCESSIVE HEAT 0 112
MS MONROE TORNADO 17 52
MS YAZOO TORNADO 4 53
NC BERTIE TORNADO 12 63
NC CUMBERLAND TORNADO 1 89
NC JOHNSTON TORNADO 0 67
NC WAKE TORNADO 4 68
NC WASHINGTON FLOOD 10 0
NV NVZ020 EXCESSIVE HEAT 8 0
NV NVZ020 HEAT 18 0
NY NYZ072>075 - 176 - 178 EXCESSIVE HEAT 7 0
OH WOOD TORNADO 7 28
OK CANADIAN TORNADO 7 112
OK CARTER TORNADO 8 46
OK CLEVELAND TORNADO 1 55
OK MCCLAIN TORNADO 0 61
OK OKLAHOMA FLASH FLOOD 1 136
PA DAUPHIN FLOOD 8 0
PA LANCASTER FLOOD 6 0
PA PAZ071 HEAT 13 0
PR ARECIBO FLASH FLOOD 8 0
TN BLEDSOE TORNADO 8 20
TN BRADLEY TORNADO 18 405
TN DAVIDSON FLOOD 10 0
TN GREENE TORNADO 14 211
TN HAMILTON TORNADO 16 206
TN RUTHERFORD TORNADO 2 58
TN TNZ021 - 088 HEAT 7 0
TN TNZ049 - 088 EXCESSIVE HEAT 7 1
TX TXZ091 - 094 - 104 - 117 HEAT 3 210
TX TXZ100 - 102 - 119 - 133 - 159 HEAT 9 223
TX TXZ119 HEAT 5 140
TX TXZ257 RIP CURRENT 7 0
VA WASHINGTON TORNADO 6 100
WY WYZ012 AVALANCHE 7 6
# Plot this with a barplot
# c(bottom, left, top, right)
par(mfrow=c(1,2), mar=c(12,3,3,1))
barplot(sdByEVTYPEByFIDFTop10$total_fatalities, 
        names=sdByEVTYPEByFIDFTop10$eventType,
        ylab="Count of Fatalities", 
        main=paste("Fatalities: ", timeFrame), 
        las=2)
# Now reorder by Injuries
sdByEVTYPEByFIDFTop10 <- 
  head(arrange(sdByEVTYPEByFIDF,
               desc(total_injuries),
               desc(total_fatalities)),10)
barplot(sdByEVTYPEByFIDFTop10$total_injuries, 
        names=sdByEVTYPEByFIDFTop10$eventType, 
        ylab="Count of Injuries", 
        main=paste("Injuries: ", timeFrame), 
        las=2)

FIGURE 2 (above): Top 10 fatalities and top 10 injuries by event type for last 3 years.
This addresses the question of which types of events are most harmful to population health.

# Reset plot to go full width across the page
par(mfrow=c(1,1), mar=c(12,4,4,4))   

barplot(sdDmgByEVTYPEByCPDFTop10$total_damage/1000000000, 
        names=sdDmgByEVTYPEByCPDFTop10$eventType, 
        ylab = "Total Damage - Billions (USD)", 
        main= paste("Top Total Storm Damage by Event Type: ", timeFrame),         
        las=2)

FIGURE 3 (above): Top 10 storm damage (combined property and crop damage) by event type for last 3 years.
This addresses the question of which types of events have the greatest economic consequences.

Conclusion

As per the graphs above, tornadoes are by far the most harmful to population health, while floods and tornadoes
have the greatest economic impact.