This paper took the public data from the U.S. National Oceanic and Atmospheric Administration (NOAA) on storms and other severe weather events and analyse the most severe events with respect to public health and economic losses. This is an assignment for the Coursera course “Reproducible Research”.
The paper describes how to get the data, the processing and cleaning data and performing the analysis.
Relevant NOAA database was downloaded, and then records and variables of interest were extracted. The economic damage amount was calculated, and the resulting data was further cleaned by looking at the event types variables and matching back to the complete list of events. Unmatched records were then mapped back to the complete list closest to the intention; finally reasonable check performed for the most significant events before summarizing the data for damages by event types.
The analysis shows that the events that caused the most fatalities were “Excessive Heat”, “Tornado” and “Flash Flood”, while those causing the most injuries were “Tornado”, “Flood” and “Excessive Heat”; he event types that caused the most economic damages are “Hurricane/Typhoon”, “Storm Surge/Tide” and “Flood”.
We also included recommendations for further research in the last section.
This section describes the source of data, the process of loading and summarizing data, including a cursory look at the data quality and where necessary imputing missing or wrong data. Throughout the document, R codes used to process the data and performing analysis were included; readers interested on the analysis result only can skip to the next section.
The data from NOAA can be downloaded from the course web site. There are also documentation of the database available on how some variables of the NOAA database are constructed:
Below R codes load the relevant libraies to be used, set the working directory, and create the data directory where necessary, and download the NOAA database and the documents above:
library(tidyverse)
library(knitr)
library(grid)
library(gridExtra)
setwd("~/Documents/R Course/Reproducible Research/Week 4/")
#set up address for data to be downloaded
urldata <- "https://d396qusza40orc.cloudfront.net/repdata%2Fdata%2FStormData.csv.bz2"
destfile <- "repdata_data_StormData.csv.bz2"
urldatadoc <- "https://d396qusza40orc.cloudfront.net/repdata%2Fpeer2_doc%2Fpd01016005curr.pdf"
urlfaq <- "https://d396qusza40orc.cloudfront.net/repdata%2Fpeer2_doc%2FNCDC%20Storm%20Events-FAQ%20Page.pdf"
docfile <- "instruction.pdf"
faqfile <- "data_faq.pdf"
#create ".data" directory if not already exist
data_dir <-"data"
if (!dir.exists(data_dir)){dir.create(data_dir)}
#download the data
download.file(urldata, file.path(data_dir,destfile))
download.file(urldatadoc, file.path(data_dir,docfile))
download.file(urlfaq, file.path(data_dir,faqfile))
#read the data into R
bzdata <- bzfile(file.path(data_dir,destfile))
data <- read.csv(bzdata)
From the NOAA website on the Storm Events Database mentioned above, not all events were collected pre-1996. In this analysis we focus the analysis on the period where all events were recorded, and exclude data of 1995 and before. As the purpose of analysis is to access health impact and economic damage, we also exclude those minor events with no injuries and fatalities, and zero economic damages, and extracted variables that are of interest:
#exclude data of 1995 and before
data <- data %>%
subset(as.numeric(substr(BGN_DATE,regexpr("/[0-9]{4}",BGN_DATE)+1,
regexpr("/[0-9]{4}",BGN_DATE)+4))>=1996)
#exclude minor events and also extract only variables that are of interest
data1 <- data %>% select(BGN_DATE, EVTYPE, FATALITIES:CROPDMGEXP, REMARKS, REFNUM) %>%
subset(PROPDMG>0 | CROPDMG>0 | FATALITIES>0 | INJURIES>0)
Next step is to compute the economic damages. According to the documentation, the damages were recorded as damage and a “damage exponent”, representing whether the damage recorded was in dollars(““), thousands(”K”), millions(“M”) or billions(“B”). The database recorded property damages and crop damages separately, in this analysis we sum the two to arrive at total economic damage. As a routine check of data integrity we first check that the property damage exponents take the expected values, and then go on to compute the economic damages:
print(unique(data1$PROPDMGEXP))
## [1] "K" "" "M" "B"
print(unique(data1$CROPDMGEXP))
## [1] "K" "" "M" "B"
#Compute the economic damages
data1 <- data1 %>% mutate(propdmgamt = PROPDMG*if_else(PROPDMGEXP=="K",10^3,
if_else(PROPDMGEXP=="M",10^6,10^9)))
data1 <- data1 %>% mutate(cropdmgamt = CROPDMG*if_else(CROPDMGEXP=="K",10^3,
if_else(CROPDMGEXP=="M",10^6,10^9)))
data1$econdmg <- data1$propdmgamt + data1$cropdmgamt
The most challenging part of the data processing is cleaning the variable corresponding to event types (EVTYPE in the database). While the Storm Event Website webpage mentioned 48 event types, the linked PDF document described the method of recording 55 event types in the appendix. In the following analysis, we will use these 55 event types. We manually typed the 55 events in a text file and load into R, and then match that against our processed data:
#load the list of 55 event types
evlist <- read.csv("data/event", header=FALSE)
#name the variable for documentation purpose
colnames(evlist) <- "EVTYPE"
#check what EVTYPE in data1 is not in in the event type list
not_match <- data1$EVTYPE[!data1$EVTYPE %in% evlist$EVTYPE]
print(unique(not_match))
## [1] "WINTER STORM" "TORNADO"
## [3] "TSTM WIND" "HIGH WIND"
## [5] "FLASH FLOOD" "FREEZING RAIN"
## [7] "EXTREME COLD" "LIGHTNING"
## [9] "HAIL" "FLOOD"
## [11] "TSTM WIND/HAIL" "EXCESSIVE HEAT"
## [13] "RIP CURRENTS" "Other"
## [15] "HEAVY SNOW" "WILD/FOREST FIRE"
## [17] "ICE STORM" "BLIZZARD"
## [19] "STORM SURGE" "Ice jam flood (minor"
## [21] "DUST STORM" "STRONG WIND"
## [23] "DUST DEVIL" "Tstm Wind"
## [25] "URBAN/SML STREAM FLD" "FOG"
## [27] "ROUGH SURF" "Heavy Surf"
## [29] "HEAVY RAIN" "Marine Accident"
## [31] "AVALANCHE" "Freeze"
## [33] "DRY MICROBURST" "WINDS"
## [35] "COASTAL STORM" "Erosion/Cstl Flood"
## [37] "River Flooding" "WATERSPOUT"
## [39] "DAMAGING FREEZE" "Damaging Freeze"
## [41] "HURRICANE" "TROPICAL STORM"
## [43] "Beach Erosion" "Heavy Rain/High Surf"
## [45] "Unseasonable Cold" "Early Frost"
## [47] "Wintry Mix" "Extreme Cold"
## [49] "DROUGHT" "Coastal Flooding"
## [51] "Torrential Rainfall" "Landslump"
## [53] "Hurricane Edouard" "Coastal Storm"
## [55] "TIDAL FLOODING" "Tidal Flooding"
## [57] "Strong Winds" "EXTREME WINDCHILL"
## [59] "Glaze" "Extended Cold"
## [61] "Whirlwind" "Heavy snow shower"
## [63] "Light snow" "COASTAL FLOOD"
## [65] "Light Snow" "MIXED PRECIP"
## [67] "COLD" "Freezing Spray"
## [69] "DOWNBURST" "Mudslides"
## [71] "Microburst" "Mudslide"
## [73] "Cold" "SNOW"
## [75] "Snow Squalls" "Wind Damage"
## [77] "Light Snowfall" "Freezing Drizzle"
## [79] "Gusty wind/rain" "GUSTY WIND/HVY RAIN"
## [81] "Wind" "Cold Temperature"
## [83] "Heat Wave" "Snow"
## [85] "COLD AND SNOW" "HEAVY SURF"
## [87] "RAIN/SNOW" "WIND"
## [89] "FREEZE" "TSTM WIND (G45)"
## [91] "Gusty Winds" "GUSTY WIND"
## [93] "TSTM WIND 40" "TSTM WIND 45"
## [95] "HARD FREEZE" "TSTM WIND (41)"
## [97] "HEAT" "RIVER FLOOD"
## [99] "TSTM WIND (G40)" "RIP CURRENT"
## [101] "HIGH SURF" "MUD SLIDE"
## [103] "SNOW AND ICE" "COASTAL FLOODING"
## [105] "AGRICULTURAL FREEZE" "WINTER WEATHER"
## [107] "STRONG WINDS" "SNOW SQUALL"
## [109] "ICY ROADS" "OTHER"
## [111] "THUNDERSTORM" "Hypothermia/Exposure"
## [113] "HYPOTHERMIA/EXPOSURE" "Lake Effect Snow"
## [115] "Freezing Rain" "Mixed Precipitation"
## [117] "BLACK ICE" "COASTALSTORM"
## [119] "LIGHT SNOW" "DAM BREAK"
## [121] "Gusty winds" "blowing snow"
## [123] "FREEZING DRIZZLE" "FROST"
## [125] "GRADIENT WIND" "UNSEASONABLY COLD"
## [127] "GUSTY WINDS" "TSTM WIND AND LIGHTNING"
## [129] "gradient wind" "Gradient wind"
## [131] "Freezing drizzle" "WET MICROBURST"
## [133] "Heavy surf and wind" "FUNNEL CLOUD"
## [135] "TYPHOON" "LANDSLIDES"
## [137] "HIGH SWELLS" "HIGH WINDS"
## [139] "SMALL HAIL" "UNSEASONAL RAIN"
## [141] "COASTAL FLOODING/EROSION" " TSTM WIND (G45)"
## [143] "TSTM WIND (G45)" "HIGH WIND (G40)"
## [145] "TSTM WIND (G35)" "GLAZE"
## [147] "COASTAL EROSION" "UNSEASONABLY WARM"
## [149] "SEICHE" "COASTAL FLOODING/EROSION"
## [151] "HYPERTHERMIA/EXPOSURE" "WINTRY MIX"
## [153] "RIVER FLOODING" "ROCK SLIDE"
## [155] "GUSTY WIND/HAIL" "HEAVY SEAS"
## [157] " TSTM WIND" "LANDSPOUT"
## [159] "RECORD HEAT" "EXCESSIVE SNOW"
## [161] "LAKE EFFECT SNOW" "FLOOD/FLASH/FLOOD"
## [163] "MIXED PRECIPITATION" "WIND AND WAVE"
## [165] "FLASH FLOOD/FLOOD" "LIGHT FREEZING RAIN"
## [167] "ICE ROADS" "HIGH SEAS"
## [169] "RAIN" "ROUGH SEAS"
## [171] "TSTM WIND G45" "NON-SEVERE WIND DAMAGE"
## [173] "WARM WEATHER" "THUNDERSTORM WIND (G40)"
## [175] "LANDSLIDE" "HIGH WATER"
## [177] " FLASH FLOOD" "LATE SEASON SNOW"
## [179] "WINTER WEATHER MIX" "ROGUE WAVE"
## [181] "FALLING SNOW/ICE" "NON-TSTM WIND"
## [183] "NON TSTM WIND" "MUDSLIDE"
## [185] "BRUSH FIRE" "BLOWING DUST"
## [187] "VOLCANIC ASH" " HIGH SURF ADVISORY"
## [189] "HAZARDOUS SURF" "WILDFIRE"
## [191] "COLD WEATHER" "WHIRLWIND"
## [193] "ICE ON ROAD" "SNOW SQUALLS"
## [195] "DROWNING" "EXTREME COLD/WIND CHILL"
## [197] "MARINE TSTM WIND" "HURRICANE/TYPHOON"
## [199] "DENSE FOG" "WINTER WEATHER/MIX"
## [201] "FROST/FREEZE" "ASTRONOMICAL HIGH TIDE"
## [203] "HEAVY SURF/HIGH SURF" "TROPICAL DEPRESSION"
## [205] "LAKE-EFFECT SNOW" "MARINE HIGH WIND"
## [207] "THUNDERSTORM WIND" "TSUNAMI"
## [209] "STORM SURGE/TIDE" "COLD/WIND CHILL"
## [211] "LAKESHORE FLOOD" "MARINE THUNDERSTORM WIND"
## [213] "MARINE STRONG WIND" "ASTRONOMICAL LOW TIDE"
## [215] "DENSE SMOKE" "MARINE HAIL"
## [217] "FREEZING FOG"
There are obvious unmatched results due to using upper/lower case and leading spaces. For ease of matching, we change both EVTYPE variables to all upper case and trim the white spaces for our processed data, and then repeat the matching process:
evlist$EVTYPE <- toupper(evlist$EVTYPE)
data1$EVTYPE <- toupper(data1$EVTYPE)
data1$EVTYPE <- trimws(data1$EVTYPE, which = "left")
#check what EVTYPE in data1 is not in in the event type list
not_match <- data1$EVTYPE[!data1$EVTYPE %in% evlist$EVTYPE]
print(unique(not_match))
## [1] "TSTM WIND" "FREEZING RAIN"
## [3] "EXTREME COLD" "TSTM WIND/HAIL"
## [5] "RIP CURRENTS" "OTHER"
## [7] "WILD/FOREST FIRE" "STORM SURGE"
## [9] "ICE JAM FLOOD (MINOR" "URBAN/SML STREAM FLD"
## [11] "FOG" "ROUGH SURF"
## [13] "HEAVY SURF" "MARINE ACCIDENT"
## [15] "FREEZE" "DRY MICROBURST"
## [17] "WINDS" "COASTAL STORM"
## [19] "EROSION/CSTL FLOOD" "RIVER FLOODING"
## [21] "DAMAGING FREEZE" "HURRICANE"
## [23] "BEACH EROSION" "HEAVY RAIN/HIGH SURF"
## [25] "UNSEASONABLE COLD" "EARLY FROST"
## [27] "WINTRY MIX" "COASTAL FLOODING"
## [29] "TORRENTIAL RAINFALL" "LANDSLUMP"
## [31] "HURRICANE EDOUARD" "TIDAL FLOODING"
## [33] "STRONG WINDS" "EXTREME WINDCHILL"
## [35] "GLAZE" "EXTENDED COLD"
## [37] "WHIRLWIND" "HEAVY SNOW SHOWER"
## [39] "LIGHT SNOW" "MIXED PRECIP"
## [41] "COLD" "FREEZING SPRAY"
## [43] "DOWNBURST" "MUDSLIDES"
## [45] "MICROBURST" "MUDSLIDE"
## [47] "SNOW" "SNOW SQUALLS"
## [49] "WIND DAMAGE" "LIGHT SNOWFALL"
## [51] "FREEZING DRIZZLE" "GUSTY WIND/RAIN"
## [53] "GUSTY WIND/HVY RAIN" "WIND"
## [55] "COLD TEMPERATURE" "HEAT WAVE"
## [57] "COLD AND SNOW" "RAIN/SNOW"
## [59] "TSTM WIND (G45)" "GUSTY WINDS"
## [61] "GUSTY WIND" "TSTM WIND 40"
## [63] "TSTM WIND 45" "HARD FREEZE"
## [65] "TSTM WIND (41)" "RIVER FLOOD"
## [67] "TSTM WIND (G40)" "MUD SLIDE"
## [69] "SNOW AND ICE" "AGRICULTURAL FREEZE"
## [71] "SNOW SQUALL" "ICY ROADS"
## [73] "THUNDERSTORM" "HYPOTHERMIA/EXPOSURE"
## [75] "LAKE EFFECT SNOW" "MIXED PRECIPITATION"
## [77] "BLACK ICE" "COASTALSTORM"
## [79] "DAM BREAK" "BLOWING SNOW"
## [81] "FROST" "GRADIENT WIND"
## [83] "UNSEASONABLY COLD" "TSTM WIND AND LIGHTNING"
## [85] "WET MICROBURST" "HEAVY SURF AND WIND"
## [87] "TYPHOON" "LANDSLIDES"
## [89] "HIGH SWELLS" "HIGH WINDS"
## [91] "SMALL HAIL" "UNSEASONAL RAIN"
## [93] "COASTAL FLOODING/EROSION" "TSTM WIND (G45)"
## [95] "HIGH WIND (G40)" "TSTM WIND (G35)"
## [97] "COASTAL EROSION" "UNSEASONABLY WARM"
## [99] "COASTAL FLOODING/EROSION" "HYPERTHERMIA/EXPOSURE"
## [101] "ROCK SLIDE" "GUSTY WIND/HAIL"
## [103] "HEAVY SEAS" "LANDSPOUT"
## [105] "RECORD HEAT" "EXCESSIVE SNOW"
## [107] "FLOOD/FLASH/FLOOD" "WIND AND WAVE"
## [109] "FLASH FLOOD/FLOOD" "LIGHT FREEZING RAIN"
## [111] "ICE ROADS" "HIGH SEAS"
## [113] "RAIN" "ROUGH SEAS"
## [115] "TSTM WIND G45" "NON-SEVERE WIND DAMAGE"
## [117] "WARM WEATHER" "THUNDERSTORM WIND (G40)"
## [119] "LANDSLIDE" "HIGH WATER"
## [121] "LATE SEASON SNOW" "WINTER WEATHER MIX"
## [123] "ROGUE WAVE" "FALLING SNOW/ICE"
## [125] "NON-TSTM WIND" "NON TSTM WIND"
## [127] "BRUSH FIRE" "BLOWING DUST"
## [129] "HIGH SURF ADVISORY" "HAZARDOUS SURF"
## [131] "COLD WEATHER" "ICE ON ROAD"
## [133] "DROWNING" "MARINE TSTM WIND"
## [135] "HURRICANE/TYPHOON" "WINTER WEATHER/MIX"
## [137] "ASTRONOMICAL HIGH TIDE" "HEAVY SURF/HIGH SURF"
There are still 137 event types not matched. While in theory one can read through the relevant remarks in the database and determine the intended event types among the 55 events, one observe that many event types are recorded with pretty clear intention. For example, “COLD” only appears once in the 55 event types and one can infer that the intention of “COLD” in the database correspond to “COLD/WINDCHILL” in the event types list. Another example is “TSTM WIND” which a search in the appendix of the above mentioned PDF refers to “THUNDERSTORM WIND”. Here we try to map the unmatched event types as close to the intention as possible without diving into detailed review of the remarks that described the event narrative in detail:
data1 <- data1 %>%
mutate(EVTYPECLEAN=case_when(
EVTYPE %in% evlist$EVTYPE ~ EVTYPE,
EVTYPE == "TSTM WIND" ~ "THUNDERSTORM WIND",
grepl("STORM SURGE", EVTYPE) ~ "STORM SURGE/TIDE",
grepl("FLASH", EVTYPE) ~ "FLASH FLOOD",
grepl("FLOOD", EVTYPE) | grepl("FLD", EVTYPE) ~ "FLOOD",
grepl("TSTM", EVTYPE) & grepl("MARINE", EVTYPE) ~ "MARINE THUNDERSTORM WIND",
grepl("SURF", EVTYPE) ~ "HIGH SURF",
grepl("RIP CURRENTS", EVTYPE) ~ "RIP CURRENT",
grepl("FREEZE", EVTYPE) | grepl("FREEZING", EVTYPE) ~ "FROST/FREEZE",
#FREEZING DRIZZLES/RAIN/SPRAY grouped to FROST/FREEZE
grepl("FROST", EVTYPE) ~ "FROST/FREEZE",
grepl("WINTER WEATHER", EVTYPE) ~ "WINTER WEATHER",
grepl("HAIL", EVTYPE) ~ "HAIL",
grepl("FIRE", EVTYPE) ~ "BLIZZARD",
grepl("MICROBURST", EVTYPE) | grepl("THUNDERSTORM", EVTYPE) ~ "THUNDERSTORM WIND",
grepl("HURRICANE", EVTYPE) | grepl("TYPHOON", EVTYPE) ~ "HURRICANE (TYPHOON)",
grepl("LANDSLIDE", EVTYPE) | grepl("MUDSLIDE", EVTYPE) ~ "DEBRIS FLOW",
grepl("COLD", EVTYPE) | grepl("CHILL", EVTYPE) ~ "COLD/WIND CHILL",
EVTYPE == "FOG" ~ "DENSE FOG",
grepl("HEAT", EVTYPE) ~ "HEAT",
TRUE ~ EVTYPE
))
not_match <- data1[!data1$EVTYPECLEAN %in% evlist$EVTYPE,]
print(unique(not_match$EVTYPE))
## [1] "OTHER" "MARINE ACCIDENT"
## [3] "WINDS" "COASTAL STORM"
## [5] "BEACH EROSION" "WINTRY MIX"
## [7] "TORRENTIAL RAINFALL" "LANDSLUMP"
## [9] "STRONG WINDS" "GLAZE"
## [11] "WHIRLWIND" "HEAVY SNOW SHOWER"
## [13] "LIGHT SNOW" "MIXED PRECIP"
## [15] "DOWNBURST" "SNOW"
## [17] "SNOW SQUALLS" "WIND DAMAGE"
## [19] "LIGHT SNOWFALL" "GUSTY WIND/RAIN"
## [21] "GUSTY WIND/HVY RAIN" "WIND"
## [23] "RAIN/SNOW" "TSTM WIND (G45)"
## [25] "GUSTY WINDS" "GUSTY WIND"
## [27] "TSTM WIND 40" "TSTM WIND 45"
## [29] "TSTM WIND (41)" "TSTM WIND (G40)"
## [31] "MUD SLIDE" "SNOW AND ICE"
## [33] "SNOW SQUALL" "ICY ROADS"
## [35] "HYPOTHERMIA/EXPOSURE" "LAKE EFFECT SNOW"
## [37] "MIXED PRECIPITATION" "BLACK ICE"
## [39] "COASTALSTORM" "DAM BREAK"
## [41] "BLOWING SNOW" "GRADIENT WIND"
## [43] "TSTM WIND AND LIGHTNING" "HIGH SWELLS"
## [45] "HIGH WINDS" "UNSEASONAL RAIN"
## [47] "TSTM WIND (G45)" "HIGH WIND (G40)"
## [49] "TSTM WIND (G35)" "COASTAL EROSION"
## [51] "UNSEASONABLY WARM" "HYPERTHERMIA/EXPOSURE"
## [53] "ROCK SLIDE" "HEAVY SEAS"
## [55] "LANDSPOUT" "EXCESSIVE SNOW"
## [57] "WIND AND WAVE" "ICE ROADS"
## [59] "HIGH SEAS" "RAIN"
## [61] "ROUGH SEAS" "TSTM WIND G45"
## [63] "NON-SEVERE WIND DAMAGE" "WARM WEATHER"
## [65] "HIGH WATER" "LATE SEASON SNOW"
## [67] "ROGUE WAVE" "FALLING SNOW/ICE"
## [69] "NON-TSTM WIND" "NON TSTM WIND"
## [71] "BLOWING DUST" "ICE ON ROAD"
## [73] "DROWNING" "ASTRONOMICAL HIGH TIDE"
The unmatched event types decreased signficantly. More important is the total no of record of these unmatched events consist of less than 1000 out of the more than 200k events in the processed data:
#no of element of not match is less than 1000
print(length(not_match$EVTYPE))
## [1] 591
We also further checked that the fatalities, injuries and economic damages of these unmatched events are at most around 1% of total:
#sum of econ and human damage also very small
print(sum(not_match$FATALITIES)/sum(data1$FATALITIES))
## [1] 0.009734311
print(sum(not_match$INJURIES)/sum(data1$INJURIES))
## [1] 0.01022855
print(sum(not_match$econdmg)/sum(data1$econdmg))
## [1] 0.0001030396
We conclude that it is safe to group all the unmatched event types entries to “OTHERS” without impacting the analysis of most impactful events.
#map the rest of cods to "OTHERS"
data1$EVTYPECLEAN <- if_else(data1$EVTYPECLEAN %in% evlist$EVTYPE,
data1$EVTYPECLEAN,"OTHERS")
As the event types issue show, there can be typos or variations from the prescribed way of recording events. While detailed review and validation of individual database entries is impractical for purpose of this research, we extracted events of economic damages exceeding US$ 1 billion and reviewed the event narratives in the remarks, to make sure that these are significant events:
manualcheck <- data1 %>% subset(PROPDMGEXP == "B" | CROPDMGEXP == "B")
write.table(select(manualcheck, REFNUM,REMARKS), "manual_check.txt")
Upon checking, record number 605943 seems to have an error - the property loss was registered at 115 billion, while the remarks mentioned only less than 100m in property damage. We believe it is reasonable to impute the data by changing it from “B” in PROPDMGEXP to “M”:
data1$PROPDMGEXP <- if_else(data1$REFNUM==605943, "M", data1$PROPDMGEXP)
data1$propdmgamt <- if_else(data1$REFNUM==605943,
data1$PROPDMG*1000000,data1$propdmgamt)
data1$econdmg <- if_else(data1$REFNUM==605943,
data1$propdmgamt+data1$cropdmgamt, data1$econdmg)
At this stage, we finished cleaning the data, and summarize the data by summing the damages (human or economic) by event types:
#summarize data for fatalities and injuries, econdmg separately
data_sumfat <-aggregate(FATALITIES ~ EVTYPECLEAN, data1, sum)
data_suminj <-aggregate(INJURIES ~ EVTYPECLEAN, data1, sum)
data_sumecon <-aggregate(econdmg ~ EVTYPECLEAN, data1, sum)
#order the resulting summary
data_sumfat <- data_sumfat[order(data_sumfat$FATALITIES, decreasing = FALSE),]
data_suminj <- data_suminj[order(data_suminj$INJURIES, decreasing = FALSE),]
data_sumecon <- data_sumecon[order(data_sumecon$econdmg, decreasing = FALSE),]
After processing data, we present the fatalities and injuries caused by different event types for the period covered:
# call ggplot and make 2 bar plot of FATALITIES / INJURIES vs EVTYPE,
# in decreasing order
plot1 <- ggplot(data_sumfat, aes(x=reorder(EVTYPECLEAN,FATALITIES,
decreasing=TRUE), y=FATALITIES)) +
geom_bar(stat="identity",width=1, fill="red") +
theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5, size = 8)) +
labs(x="Event",y="Fatalities",title="No. of Fatalities by Event Type")
plot2 <- ggplot(data_suminj, aes(x=reorder(EVTYPECLEAN,INJURIES,
decreasing=TRUE), y=INJURIES)) +
geom_bar(stat="identity",width=1, fill="blue") +
theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5, size = 8)) +
labs(x="Event",y="Injuries",title="No. of Injuries by Event Type")
#Arrange the two chart in a column
g1 <- grid.arrange(plot1,plot2,ncol=2,top=textGrob("Population Health Impacts by Events"))
print(g1)
## TableGrob (2 x 2) "arrange": 3 grobs
## z cells name grob
## 1 1 (2-2,1-1) arrange gtable[layout]
## 2 2 (2-2,2-2) arrange gtable[layout]
## 3 3 (1-1,1-2) arrange text[GRID.text.79]
From the chart, the events that caused the most fatalities were “Excessive Heat”, “Tornado” and “Flash Flood”, while those causing the most injuries were “Tornado”, “Flood” and “Excessive Heat”.
Similarly we plot the economic by damage type, ordering by the ammount of damages, in the chart below:
#Similarly, plot the economic damages by event. In this context we only show the
#total of property damages and crop damages
g2 <- ggplot(data_sumecon, aes(x=reorder(EVTYPECLEAN,econdmg,
decreasing=TRUE), y=econdmg/1000000000)) +
geom_bar(stat="identity",width=1, fill="red") +
theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5, size = 8)) +
labs(x="Event",y="Economic Losses",title="Losses by Event Type (US$ Billion)")
print(g2)
From the chart above, the event types that caused the most economic
damages are “Hurricane/Typhoon”, “Storm Surge/Tide” and “Flood”.
One observation from the above is a few severe event types caused the bulk of population health losses and economic losses. From there one can consider what can be done to lessen the impacts from these events.
An improvement of the analysis is to convert the economic losses to present day dollar value, adjusting for inflation. Further study is needed on the methodology of loss estimations, as the instruction seems to be based on tables that may or may not be adjusted for inflation. Also need to track the history of update of these instructions.
Another improvement is to improve the data cleaning process and reduce the unmatched event type further. Data validation should be done before more refined studies are done, in view of the data quality of input data as reflected in the event type variable.