Synopsis

This analysis explores the NOAA Storm Database to identify which types of severe weather events have the greatest impact on population health and the economy in the United States. Using data from 1950 to 2011, the study summarizes fatalities, injuries, and economic damages associated with different event types. The results highlight the top weather events that cause the most harm to people and the highest economic losses, providing valuable insights for disaster preparedness and resource prioritization.


About the Data

The data for this assignment come in the form of a comma-separated-value file compressed via the bzip2 algorithm to reduce its size. You can download the file from the course web site:

There is also some documentation of the database available. Here you will find how some of the variables are constructed/defined.

The events in the database start in the year 1950 and end in November 2011. In the earlier years of the database there are generally fewer events recorded, most likely due to a lack of good records. More recent years should be considered more complete.


Data Processing


Load Libraries

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(stringr)
library(tidyr)
library(ggplot2)


Data Loading
The Storm Data file is retrieved directly from the URL using download.file(), and then read into R using read.csv().


Download and read data file

url <- "https://d396qusza40orc.cloudfront.net/repdata%2Fdata%2FStormData.csv.bz2"
destfile <- "StormData.csv.bz2"
download.file(url, destfile, mode = "wb")
rawdata <- read.csv(destfile)


Data Transformation
The EVTYPE field requires standardization due to inconsistent capitalization and extra spaces (e.g., “Tornado”, “TORNADO”, ” tornado “). We clean this field by trimming any leading or trailing whitespace and converting all event type entries to uppercase. This standardization allows for consistent aggregation and comparison across event types.


Create ‘clean’ event types

data <- rawdata %>%
        mutate(Event = str_trim(EVTYPE),
               Event = str_to_upper(Event))


Property and crop damage values are recorded with suffixes indicating scale, such as “K” for thousands and “M” for millions. These values need to be converted from their string representations into numeric values to enable meaningful comparison and aggregation of damage amounts across different event types. This transformation ensures that damage data is accurate and comparable.


Map the damage exponents to their numeric multipliers

exp_to_num <- function(e) {
        e <- toupper(as.character(e))
        ifelse(e == "H", 1e2,
        ifelse(e == "K", 1e3,
        ifelse(e == "M", 1e6,
        ifelse(e == "B", 1e9,
        ifelse(e %in% c("", "+", "-", "?"), 1,
        ifelse(grepl("^[0-8]$", e), 10^as.numeric(e), 1))))))
}


Add columns for actual property and crop damages

data <- data %>%
        mutate(PropMult = exp_to_num(PROPDMGEXP),
               CropMult = exp_to_num(CROPDMGEXP),
               PropertyDamage = PROPDMG * PropMult,
               CropDamage = CROPDMG * CropMult,
               TotalDamage = PropertyDamage + CropDamage
        )
## Warning: There were 2 warnings in `mutate()`.
## The first warning was:
## ℹ In argument: `PropMult = exp_to_num(PROPDMGEXP)`.
## Caused by warning in `ifelse()`:
## ! NAs introduced by coercion
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 1 remaining warning.

Note:
When converting the damage exponent fields, you may see a warning: “NAs introduced by coercion”.
This occurs because some exponent codes are non-numeric (e.g., “K”, “M”, “B”, or symbols). Our function explicitly handles all valid codes, and any unexpected or missing values are safely assigned a multiplier of 1.
The warning can be safely ignored for this analysis.


Results


1. Events that have the greated impact on population health
To identify the most harmful event types for population health, we aggregate the total number of fatalities and injuries for each event type across the entire dataset. We then select the top 10 event types with the highest combined total of fatalities and injuries.


Summarize fatalities and injuries by event type

health_impact <- data %>%
        group_by(Event) %>%
        summarise(Fatalities = sum(FATALITIES, na.rm = TRUE),
                  Injuries = sum(INJURIES, na.rm = TRUE),
                  Total = Fatalities + Injuries
        )


Get top 10 events by total health impact

top10 <- health_impact %>%
        arrange(desc(Total)) %>%
        slice_head(n = 10) %>%
        select(Event, Fatalities, Injuries)
top10_long <- top10 %>%
        pivot_longer(cols = c(Fatalities, Injuries), 
                     names_to = "Type", 
                     values_to = "Count"
                     )


Identify top event for health impact

top_health_event <- str_to_title(top10$Event[1])


Plot top 10 events with the greatest impact to population health

ggplot(top10_long, 
       aes(x = reorder(Event, -Count), 
           y = Count, 
           fill = Type)
       ) +
        geom_col() +
        labs(title = "Top 10 Weather Events by Total Health Impact",
             x = "Event Type",
             y = "Number of People Affected",
             fill = "Type"
        ) +
        theme_minimal() +
        theme(axis.text.x = element_text(angle = 45, hjust = 1))
Fig 1: Top 10 Events with greatest impact to population health.

Fig 1: Top 10 Events with greatest impact to population health.


As shown in Figure 1, Tornado is the most harmful weather event for population health, causing the highest combined number of fatalities and injuries.



2. Events that have the greatest economic consequences
To determine which event types have the greatest economic impact, we sum the total property and crop damages for each event type and select the top 10 by total economic loss.


Summarize and get top 10 Event Types

econ_impact <- data %>%
        group_by(Event) %>%
        summarise(PropertyDamage = sum(PropertyDamage, na.rm = TRUE),
                  CropDamage = sum(CropDamage, na.rm = TRUE),
                  TotalDamage = sum(TotalDamage, na.rm = TRUE)
        )
top10_econ <- econ_impact %>%
        arrange(desc(TotalDamage)) %>%
        slice_head(n = 10)

top10_econ_long <- top10_econ %>%
        select(Event, PropertyDamage, CropDamage) %>%
        pivot_longer(cols = c(PropertyDamage, CropDamage),
                     names_to = "Type", values_to = "Amount"
                     )


Identify top event for economic impact

top_econ_event <- str_to_title(top10_econ$Event[1])


Plot top 10 events with the greatest economic consequences

ggplot(top10_econ_long, 
       aes(x = reorder(Event, -Amount), 
           y = Amount/1e9, fill = Type)
       ) +
        geom_col() +
        labs(title = "Top 10 Weather Events by Economic Damage",
             x = "Event Type",
             y = "Total Damage (Billion USD)",
             fill = "Damage Type"
        ) +
        theme_minimal() +
        theme(axis.text.x = element_text(angle = 45, hjust = 1))
Fig 2: Top 10 Events with greatest economic consequences.

Fig 2: Top 10 Events with greatest economic consequences.


Figure 2 shows that Flood leads to the greatest economic damage, with property losses.