Goals

The main goals of this exploratory data analysis is see 1. across the United States, which types of events (as indicated in the EVTYPE variable) are most harmful with respect to population health 2. Across the United States, which types of events have the greatest economic consequences?

Dataprocessing

The data is loaded. After carefull examination many error persist in the column “EVtypes”. This could lead to different classification of events so they are adjusted accordingly. Firstly, the double entry where upper and lower case error exist are adjusted, secondly the cases with punctation difference and abbreviations.

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(ggplot2)
library(tidyr)
WeatherDf <- read.csv("repdata_data_StormData1.csv")
WeatherDf <- WeatherDf %>%
  mutate(
    # 1. Convert to UPPERCASE
    EVTYPE = toupper(EVTYPE),
   
    # 2. Collapse internal extra spaces and trim edges (e.g., "FLASH   FLOOD" -> "FLASH FLOOD")
    EVTYPE = str_squish(EVTYPE),
   
    # 3. Remove non-alphanumeric punctuation and abbreviation
    EVTYPE = gsub("[^A-Z0-9 ]", " ", EVTYPE),
    EVTYPE = str_squish(EVTYPE),
    EVTYPE = gsub("^TSTM", "THUNDERSTORM", EVTYPE)
  )

Secondly, common abbrevation mistakes are adjusted as well as common term that are under the same case are bundles together like so. Please note that this was done quite quick and dirty as this is not the primary purpose of this assignment.

WeatherDf <- WeatherDf %>%
  mutate(
    EVTYPE_CLEAN = case_when(
      # Catch anything thunderstomr related
      str_detect(EVTYPE, "^THU|^THST|^TSTM") ~ "THUNDERSTORM",
     
      # Catch anything starting tornado
      str_detect(EVTYPE, "^TORN|TORND") ~ "TORNADO",
     
      # Fallback to original text if no pattern matches
      TRUE ~ EVTYPE
    )
  )

WeatherDf <- WeatherDf %>%
  mutate(
    EVTYPE = case_when(
      EVTYPE %in% c("RECORD EXCESSIVE HEAT", "HEAT WAVE DROUGHT") ~ "EXTREME HEAT",
      EVTYPE %in% c("TSTM WIND", "MARINE TSTM WIND", "MARINE THUNDERSTORM WIND", "THUNDERSTORM WIND", "LIGHTNING", "THUNDERSTORMW") ~ "THUNDERSTORM WINDS",
      EVTYPE %in% c("HAIL", "HEAVY SNOW", "WINTER STORM", "COLD AND SNOW", "GLAZE ICE STORM") ~ "WINTER WEATHER",
      EVTYPE %in% c("FLASH FLOOD") ~ "FLOOD",
      EVTYPE %in% c("RECORD EXCESSIVE HEAT", "HEAT WAVE DROUGHT", "HEAT WAVE", "HEAT WAVE") ~ "EXTREME HEAT",
      EVTYPE %in% c("TROPICAL STORM GORDON") ~ "TROPICAL STORM",
      EVTYPE %in% c("TORNADOES TSTM WIND HAIL") ~ "TORNADO",
      EVTYPE %in% c("HIGH WIND AND SEAS", "HEAVY SURF AND WIND") ~ "ROUGH SEAS",    
      TRUE ~ EVTYPE  # keeps all other values unchanged
    )
  )

In order to later in the analysis look a the ecomonic impact the correct nummeric values are calculated

# Helper function to convert exponential characters into numeric multipliers
get_multiplier <- function(exp) {
  exp <- toupper(as.character(exp))
  case_when(
    exp == "K" ~ 1e3,  # Thousands
    exp == "M" ~ 1e6,  # Millions
    exp == "B" ~ 1e9,  # Billions
    exp == "H" ~ 1e2,  # Hundreds
    TRUE       ~ 1     # Default to 1 for unformatted or missing values
  )
}

# Calculate true dollar values and total economic impact
WeatherDf <- WeatherDf %>%
  mutate(
    # Convert character multipliers to numbers
    prop_mult = get_multiplier(PROPDMGEXP),
    crop_mult = get_multiplier(CROPDMGEXP),
   
    # Compute full dollar amounts
    REAL_PROPDMG = PROPDMG * prop_mult,
    REAL_CROPDMG = CROPDMG * crop_mult,
   
    # Total Economic Impact
    ECONOMIC_IMPACT = REAL_PROPDMG + REAL_CROPDMG
  )

Results

In the next figure we can see a combination of both the average injuries and casualties to quantify the impact on the population health. This indicates that to prevent the biggest impact on population health wild fires, (snow) storms and extreme heat should be adressed.

# Standardize / clean data and calculate averages
plot_data <- WeatherDf %>%
  group_by(EVTYPE) %>%
  summarise(
    Injuries = mean(INJURIES, na.rm = TRUE),
    Fatalities = mean(FATALITIES, na.rm = TRUE)
  ) %>%
  # Combine to find the top 10 highest-impact weather conditions
  mutate(total_avg = Injuries + Fatalities) %>%
  slice_max(order_by = total_avg, n = 10) %>%
  select(-total_avg) %>%
  # Reshape data into long format for ggplot
  pivot_longer(
    cols = c(Injuries, Fatalities),
    names_to = "Casualty_Type",
    values_to = "Average_Count"
  )
## `summarise()` ungrouping output (override with `.groups` argument)
# Create grouped bar chart
ggplot(plot_data, aes(x = reorder(EVTYPE, Average_Count), y = Average_Count, fill = Casualty_Type)) +
  geom_col(position = "dodge", width = 0.7) +
  coord_flip() +
  scale_fill_manual(values = c("Fatalities" = "#d95f02", "Injuries" = "#7570b3")) +
  labs(
    title = "Top 10 Weather Conditions by Average Harm",
    subtitle = "Average number of injuries and fatalities per recorded event",
    x = "Weather Event Type",
    y = "Average Count per Event",
    fill = "Metric"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    legend.position = "bottom",
    plot.title = element_text(face = "bold")
  )

To see the impact of the weather event on the economy the average loss was plotted per event type. This showed that heavy rain was most impactfull followed by hurricane typhoon.

top_economic <- WeatherDf %>%
  group_by(EVTYPE_CLEAN) %>% # Uses your cleaned weather column
  summarise(avg_impact = mean(ECONOMIC_IMPACT, na.rm = TRUE)) %>%
  slice_max(order_by = avg_impact, n = 10)
## `summarise()` ungrouping output (override with `.groups` argument)
ggplot(top_economic, aes(x = reorder(EVTYPE_CLEAN, avg_impact), y = avg_impact / 1e6)) +
  geom_col(fill = "#2b8cbe", width = 0.7) +
  coord_flip() +
  labs(
    title = "Top 10 Weather Events by Average Economic Impact",
    x = "Weather Event Type",
    y = "Average Loss (Millions USD)"
  ) +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold"))