Reproducible Research: Project 2

Synopsis

The analysis begins with reading the raw csv file into R. From here a data subset only containing the variables of interest to population health is created. Population health will be measured using the fatalities and injuries variables. Then the mean, median and total sum for both fatalities and injuries across all storm events.

The next step is to create another data subset with the variables representing economic consequences, which are property and crop damage as well as the respective codes describing the scale of damage. This analysis is more complicated as the letter code representing the dollar amount scale first has to be replaced and any blanks and other characters in the column have to be cleared prior to calculation. The raw numeric value for both property and crop damage are then multiplied by the numeric scale and these products are added to the data. Finally, through simple addition the scaled crop and property damage are added together and then the total financial damage per each storm category is calculated.

Finally, graphs are created to easily visualize the data.

Data Processing

Loading the Data in

First we create a new directory for the project and read the raw csv file into R.

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.4.4     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
dir.create("project2")
## Warning in dir.create("project2"): 'project2' already exists
## Reading the Data In
storm_raw <- read.csv("./project2/repdata_data_StormData.csv")

Creating the Health Data Subset

The columns of interest are selected from the raw data and made into a smaller data frame. The structure of this is checked to ensure we have the variables of interest.

## Creating the first Data subset
health0 <- select(storm_raw, 1:8, FATALITIES, INJURIES)
str(health0)
## 'data.frame':    902297 obs. of  10 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" ...
##  $ FATALITIES: num  0 0 0 0 0 0 0 0 1 0 ...
##  $ INJURIES  : num  15 0 2 2 2 6 1 0 14 0 ...

Determining Which Events are the Most Harmful

The following code chunk groups the data by each storm event listed and the calculates mean, median and total sum for both injuries and fatalities. http://127.0.0.1:12097/graphics/4737c078-975e-4d49-9b45-d2c95530221e.png

## Determining Which Events are Most Harmful
harm <- health0 %>% 
  group_by(EVTYPE) %>% 
  summarize(meanf = as.integer(mean(FATALITIES)), medianf = median(FATALITIES),
            sumf = sum(FATALITIES), meani = as.integer(mean(INJURIES)), 
            mediani = median(INJURIES), sumi = sum(INJURIES))

Subsetting for Plots

Looking at the data, it will be most informative to plot median and sum of both injuries and fatalities. As we cannot plot every single storm type we choose to plot the top 10 with the most fatalities and injuries by both median and total. To make it easier to create our plots the following code simply subsets and creates smaller data frames of the top 10 storm events for each category.

## Creating Smaller Datasets to Plot
median_f <- harm %>%
  arrange(desc(medianf)) 
median_f <- as.data.frame(median_f[1:10,])

median_i <- harm %>% 
  arrange(desc(mediani))
median_i <- median_i[1:10, ] 

sum_f <- harm %>%
  arrange(desc(sumf))
sum_f <- sum_f[1:10, ]

sum_i <- harm %>% 
  arrange(desc(sumi))
sum_i <- sum_i[1:10, ]

Economic Damage Subset

Looking at the variables, to determine economic consequences it seems the best way is to see which events caused the greatest overall combined and crop and property damage. This code selects the variables we need for that analysis.

## Creating the Second Data subset
cost <- select(storm_raw, 1:8, PROPDMG, PROPDMGEXP, CROPDMG, CROPDMGEXP)

Correcting the Cost Code

The data set comes with a code by which to scale the raw numeric damage values. This code assigns letters specifying a certain dollar value to scale by ex.(m = millions, h = hundreds, etc.). We need to convert this in order to calculate the true damage values in USD. The below code converts all the letter code to appropriate numeric values for both the property and crop scales. Furthermore, all blanks and other characters and replaced to allow the vectors to be converted to numeric for the coming calculations.

We implement the updated numeric vectors into the data frame then check the structure is correct.

It should be noted that for our calculations it was decided to only use the values that specified a numeric coded letter to scale by. The blanks and other characters were considered incomplete data.

## Correcting the Costs
table(cost$PROPDMGEXP)
## 
##             -      ?      +      0      1      2      3      4      5      6 
## 465934      1      8      5    216     25     13      4      4     28      4 
##      7      8      B      h      H      K      m      M 
##      5      1     40      1      6 424665      7  11330
table(cost$CROPDMGEXP)
## 
##             ?      0      2      B      k      K      m      M 
## 618413      7     19      1      9     21 281832      1   1994
cost <- cost %>% 
  filter(PROPDMGEXP == "M" | PROPDMGEXP ==  "m" | PROPDMGEXP == "K" | 
           PROPDMGEXP == "h" | PROPDMGEXP == "H" | PROPDMGEXP == "B" | CROPDMGEXP == "B" |
           CROPDMGEXP == "k" |CROPDMGEXP == "K" | CROPDMGEXP == "m" | CROPDMGEXP == "M")
cost1<- gsub("K", "1000", cost$PROPDMGEXP)
cost2 <- gsub("B", "1000000000", cost1)
cost3 <- gsub("h", "100", cost2)
cost4 <- gsub("H", "100", cost3)
cost5 <- gsub("M", "1000000", cost4)
cost6 <- gsub("m", "1000000", cost5)
cost7 <- gsub("^$", "0", cost6)
table(cost7)
## cost7
##          0        100       1000    1000000 1000000000          3          5 
##       4317          7     424665      11337         40          1          2
cost7 <- as.numeric(cost7)
cost$PROPDMGEXP <- cost7

crop1<- gsub("K", "1000", cost$CROPDMGEXP)
crop2 <- gsub("B", "1000000000", crop1)
crop3 <- gsub("k", "1000", crop2)
crop4 <- gsub("M", "1000000", crop3)
crop5 <- gsub("m", "1000000", crop4)
crop6 <- gsub("\\?", "0", crop5)
crop7 <- gsub("^$", "0", crop6)
crop7 <- as.numeric(crop7)
table(crop7)
## crop7
##      0   1000  1e+06  1e+09 
## 156512 281853   1995      9
cost$CROPDMGEXP <- crop7
str(cost)
## 'data.frame':    440369 obs. of  12 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" ...
##  $ PROPDMG   : num  25 2.5 25 2.5 2.5 2.5 2.5 2.5 25 25 ...
##  $ PROPDMGEXP: num  1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 ...
##  $ CROPDMG   : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ CROPDMGEXP: num  0 0 0 0 0 0 0 0 0 0 ...

Creating the Data to Plot

To create the data for plotting the raw numeric damage is first multiplied by the scale for both crops and property. Those are then added together to give a total cost of damage for every observation.

As before, the data as grouped by event type and then the total sum of all economic damage in USD is calculated per each event. Again, there are too many events to plot so we choose the top 10 with the impact for our final graph.

Note: Median was calculated as well but proved non-informative as many of the top 10 were simply single observations/events that caused large damage and not representative of the actual total for each event.

## Creating the Dataset for Plotting

cost <- cost %>% 
  mutate(prop_dmg = PROPDMG*PROPDMGEXP) %>% 
  mutate(crop_dmg = CROPDMG*CROPDMGEXP) %>% 
  mutate(total_dmg = prop_dmg + crop_dmg)

dmg <- cost %>% 
  filter(total_dmg > 0) %>%
  group_by(EVTYPE) %>%
  summarize(sum = sum(total_dmg), median = median(total_dmg)) %>%
  arrange(desc(sum))

dmg_final <- dmg[1:10,]

Results

Question 1: Harm to Population Health

The following code creates four bar plots, the op row is fatalities and the bottom row is injuries. The left column represents medians and the right column total sum. From the plots the single event causing the most fatalities by both median per event and total sum in the entire country are Tornados.

When looking at injuries however, the even causing the most median injuries per event are Heat Waves, while the event with the greatest total sum of injuries across the entire country was again Tornados.

## Creating Plots 
par(mfrow = c(2,2), mar = c(8,4,3,4), las = 2 )
with(median_f,(barplot(medianf ~ EVTYPE, cex.names = 0.7,
  names.arg = c("Cold and Snow", "Heat Wave Drought", "Heat Waves", "Heavy Surf and Wind",
                "High Wind and Seas", "High Wind/Seas", "Marine Mishap",
                "Rip Currents/Heavy Surf", "Tornados",
                "Tropical Storm Gordon"), xlab = "", ylab = "Median Fatalities",
  col = "firebrick", main = "Top 10 Storm Events by Median Fatalities")))
##       [,1]
##  [1,]  0.7
##  [2,]  1.9
##  [3,]  3.1
##  [4,]  4.3
##  [5,]  5.5
##  [6,]  6.7
##  [7,]  7.9
##  [8,]  9.1
##  [9,] 10.3
## [10,] 11.5
with(sum_f, (barplot(sumf ~ EVTYPE, cex.names = 0.7, names.arg =
                       c("Avalanche", "Excessive Heat", "Flash Flood", "Flood", "Heat", "High Wind",
                         "Lightning", "Rip Current", "Tornado", "Thunderstorm"), 
                     xlab = "", ylab = "Total Fatalities", 
                     main = "Top 10 Storm Events by Total Fatalities", col = "firebrick")))
##       [,1]
##  [1,]  0.7
##  [2,]  1.9
##  [3,]  3.1
##  [4,]  4.3
##  [5,]  5.5
##  [6,]  6.7
##  [7,]  7.9
##  [8,]  9.1
##  [9,] 10.3
## [10,] 11.5
with(median_i,(barplot(mediani ~ EVTYPE, cex.names = 0.7,
  names.arg = c("Ice Storm", "Heat Wave", "Heat Wave/Drought", "High Wind and Seas",
                "Wind Damage", "Snow + High Winds", "Thunderstorm", "Tornado",
                "Tropical Storm Gordon", "Winter Storm"), xlab = "",
  ylab = "Median Injuries", main = "Top 10 Storm Events by Median Injuries", col = "dodgerblue2")))
##       [,1]
##  [1,]  0.7
##  [2,]  1.9
##  [3,]  3.1
##  [4,]  4.3
##  [5,]  5.5
##  [6,]  6.7
##  [7,]  7.9
##  [8,]  9.1
##  [9,] 10.3
## [10,] 11.5
with(sum_i, barplot(sumi ~ EVTYPE, cex.names = 0.7, names.arg = 
  c("Excessive Heat", "Flash Flood", "Flood", "Hail", "Heat", "Ice Storm",
    "Lightning", "Thunderstorm Wind", "Tornado", "Thunderstorm"), xlab = "",
  ylab = "Total Injuries", main = "Top 10 Storm Events by Total Injuries",
  col = "dodgerblue2", cex.axis = 0.7))

Question 2: Economic Consequences

The below code plots the total economic consequences, which is defined at total sum across the entire country in terms of both property and crop damage for each weather event. The event causing the most economic harm was by far floods which more than doubled the second place event which were Hurricanes + Typhoons. While not as dire as the population health consequences, tornados were still very costly economically being the event causing the third most economic harm overall.

## Plotting

ggplot(data = dmg_final) +
  geom_col(mapping = aes(x = EVTYPE, y = sum), fill = "chartreuse4", col = "black") + 
  theme_bw(base_size = 7) +
  labs(x = "Event Type", y = "Total Cost (USD)", title = "Top 10 Storm Events in the United States by Economic Damage Caused",
       subtitle = "Note: economic cost is equal to combined cost of both crop damage and property damage")

Thank you for reading! That concludes the analysis for this assignment.