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:
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.
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 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)
# 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.")
| 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.
As per the graphs above, tornadoes are by far the most harmful to
population health, while floods and tornadoes
have the greatest economic impact.