Celem niniejszej analizy jest identyfikacja najbardziej
niebezpiecznych zjawisk pogodowych w Stanach Zjednoczonych w latach
1950–2011 na podstawie danych NOAA Storm Database. Analiza skupia się na
dwóch aspektach: zagrożeniach dla zdrowia publicznego oraz stratach
ekonomicznych. Dane zostały pobrane z oryginalnego pliku CSV w formacie
.bz2, a następnie przefiltrowane i przekształcone przy
użyciu R. Dla każdego typu zjawiska pogodowego obliczono sumaryczną
liczbę ofiar (śmiertelnych i rannych) oraz wysokość strat materialnych.
Wyniki zostały zilustrowane za pomocą wykresów słupkowych i tabel.
Największe zagrożenie dla zdrowia stanowiły tornada, natomiast
największe straty finansowe przyniosły huragany i powodzie. Analiza
została opublikowana na platformie RPubs.
library(dplyr)
##
## Dołączanie pakietu: 'dplyr'
## Następujące obiekty zostały zakryte z 'package:stats':
##
## filter, lag
## Następujące obiekty zostały zakryte z 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2)
## Warning: pakiet 'ggplot2' został zbudowany w wersji R 4.3.3
library(readr)
## Warning: pakiet 'readr' został zbudowany w wersji R 4.3.3
data <- read_csv("data_StormData.csv.bz2")
## Rows: 902297 Columns: 37
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (18): BGN_DATE, BGN_TIME, TIME_ZONE, COUNTYNAME, STATE, EVTYPE, BGN_AZI,...
## dbl (18): STATE__, COUNTY, BGN_RANGE, COUNTY_END, END_RANGE, LENGTH, WIDTH, ...
## lgl (1): COUNTYENDN
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# sprawdzenie struktury danych
str(data)
## spc_tbl_ [902,297 × 37] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ STATE__ : num [1:902297] 1 1 1 1 1 1 1 1 1 1 ...
## $ BGN_DATE : chr [1:902297] "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 [1:902297] "0130" "0145" "1600" "0900" ...
## $ TIME_ZONE : chr [1:902297] "CST" "CST" "CST" "CST" ...
## $ COUNTY : num [1:902297] 97 3 57 89 43 77 9 123 125 57 ...
## $ COUNTYNAME: chr [1:902297] "MOBILE" "BALDWIN" "FAYETTE" "MADISON" ...
## $ STATE : chr [1:902297] "AL" "AL" "AL" "AL" ...
## $ EVTYPE : chr [1:902297] "TORNADO" "TORNADO" "TORNADO" "TORNADO" ...
## $ BGN_RANGE : num [1:902297] 0 0 0 0 0 0 0 0 0 0 ...
## $ BGN_AZI : chr [1:902297] NA NA NA NA ...
## $ BGN_LOCATI: chr [1:902297] NA NA NA NA ...
## $ END_DATE : chr [1:902297] NA NA NA NA ...
## $ END_TIME : chr [1:902297] NA NA NA NA ...
## $ COUNTY_END: num [1:902297] 0 0 0 0 0 0 0 0 0 0 ...
## $ COUNTYENDN: logi [1:902297] NA NA NA NA NA NA ...
## $ END_RANGE : num [1:902297] 0 0 0 0 0 0 0 0 0 0 ...
## $ END_AZI : chr [1:902297] NA NA NA NA ...
## $ END_LOCATI: chr [1:902297] NA NA NA NA ...
## $ LENGTH : num [1:902297] 14 2 0.1 0 0 1.5 1.5 0 3.3 2.3 ...
## $ WIDTH : num [1:902297] 100 150 123 100 150 177 33 33 100 100 ...
## $ F : num [1:902297] 3 2 2 2 2 2 2 1 3 3 ...
## $ MAG : num [1:902297] 0 0 0 0 0 0 0 0 0 0 ...
## $ FATALITIES: num [1:902297] 0 0 0 0 0 0 0 0 1 0 ...
## $ INJURIES : num [1:902297] 15 0 2 2 2 6 1 0 14 0 ...
## $ PROPDMG : num [1:902297] 25 2.5 25 2.5 2.5 2.5 2.5 2.5 25 25 ...
## $ PROPDMGEXP: chr [1:902297] "K" "K" "K" "K" ...
## $ CROPDMG : num [1:902297] 0 0 0 0 0 0 0 0 0 0 ...
## $ CROPDMGEXP: chr [1:902297] NA NA NA NA ...
## $ WFO : chr [1:902297] NA NA NA NA ...
## $ STATEOFFIC: chr [1:902297] NA NA NA NA ...
## $ ZONENAMES : chr [1:902297] NA NA NA NA ...
## $ LATITUDE : num [1:902297] 3040 3042 3340 3458 3412 ...
## $ LONGITUDE : num [1:902297] 8812 8755 8742 8626 8642 ...
## $ LATITUDE_E: num [1:902297] 3051 0 0 0 0 ...
## $ LONGITUDE_: num [1:902297] 8806 0 0 0 0 ...
## $ REMARKS : chr [1:902297] NA NA NA NA ...
## $ REFNUM : num [1:902297] 1 2 3 4 5 6 7 8 9 10 ...
## - attr(*, "spec")=
## .. cols(
## .. STATE__ = col_double(),
## .. BGN_DATE = col_character(),
## .. BGN_TIME = col_character(),
## .. TIME_ZONE = col_character(),
## .. COUNTY = col_double(),
## .. COUNTYNAME = col_character(),
## .. STATE = col_character(),
## .. EVTYPE = col_character(),
## .. BGN_RANGE = col_double(),
## .. BGN_AZI = col_character(),
## .. BGN_LOCATI = col_character(),
## .. END_DATE = col_character(),
## .. END_TIME = col_character(),
## .. COUNTY_END = col_double(),
## .. COUNTYENDN = col_logical(),
## .. END_RANGE = col_double(),
## .. END_AZI = col_character(),
## .. END_LOCATI = col_character(),
## .. LENGTH = col_double(),
## .. WIDTH = col_double(),
## .. F = col_double(),
## .. MAG = col_double(),
## .. FATALITIES = col_double(),
## .. INJURIES = col_double(),
## .. PROPDMG = col_double(),
## .. PROPDMGEXP = col_character(),
## .. CROPDMG = col_double(),
## .. CROPDMGEXP = col_character(),
## .. WFO = col_character(),
## .. STATEOFFIC = col_character(),
## .. ZONENAMES = col_character(),
## .. LATITUDE = col_double(),
## .. LONGITUDE = col_double(),
## .. LATITUDE_E = col_double(),
## .. LONGITUDE_ = col_double(),
## .. REMARKS = col_character(),
## .. REFNUM = col_double()
## .. )
## - attr(*, "problems")=<externalptr>
# wybor kolumn istotnych dla analizy
storm <- data %>%
select(EVTYPE, FATALITIES, INJURIES, PROPDMG, PROPDMGEXP, CROPDMG, CROPDMGEXP)
# przeliczanie wartosci z sufixem exp -> aby moc obliczyc faktyczne straty
convert_exp <- function(value, exp) {
exp <- toupper(exp)
multiplier <- case_when(
exp == "K" ~ 1e3,
exp == "M" ~ 1e6,
exp == "B" ~ 1e9,
exp %in% c("", "+", "-", "?") ~ 1,
TRUE ~ 0
)
return(value * multiplier)
}
# obliczanie lacznych strat i wplywu na zdrowie
storm <- storm %>%
mutate(
PROPDMGVAL = convert_exp(PROPDMG, PROPDMGEXP),
CROPDMGVAL = convert_exp(CROPDMG, CROPDMGEXP),
TOTALDMG = PROPDMGVAL + CROPDMGVAL,
HEALTH_IMPACT = FATALITIES + INJURIES
)
health_impact <- storm %>%
group_by(EVTYPE) %>%
summarise(Total_Health_Impact = sum(HEALTH_IMPACT, na.rm = TRUE)) %>%
arrange(desc(Total_Health_Impact)) %>%
slice_head(n = 10)
ggplot(health_impact, aes(x = reorder(EVTYPE, Total_Health_Impact), y = Total_Health_Impact)) +
geom_col(fill = "firebrick") +
coord_flip() +
labs(title = "10 najbardziej szkodliwych zjawisk pogodowych dla zdrowia (1950–2011)",
x = "Typ zjawiska", y = "Łączna liczba ofiar (rannych i zmarłych)") +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
plot.title.position = "plot",
plot.margin = margin(t = 30, r = 20, b = 20, l = 20)
)
economic_impact <- storm %>%
group_by(EVTYPE) %>%
summarise(Total_Damage = sum(TOTALDMG, na.rm = TRUE)) %>%
arrange(desc(Total_Damage)) %>%
slice_head(n = 10)
ggplot(economic_impact, aes(x = reorder(EVTYPE, Total_Damage), y = Total_Damage / 1e9)) +
geom_col(fill = "darkblue") +
coord_flip() +
labs(title = "10 zjawisk powodujących największe straty ekonomiczne (1950–2011)",
x = "Typ zjawiska", y = "Łączne straty (mld USD)") +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
plot.title.position = "plot",
plot.margin = margin(t = 30, r = 20, b = 20, l = 20)
)
## Czy ten wynik ma sens? ZDROWIE PUBLICZNE
Tornada są najbardziej szkodliwe — zgodne z rzeczywistością, bo powodują bardzo szybkie i silne zniszczenia, często bez dużego czasu na ewakuację.
Upały (Excessive Heat) również istotne — wpływają szczególnie na osoby starsze i osoby z chorobami serca.
STRATY EKONOMICZNE
Powodzie (Flood) prowadzą do największych szkód ekonomicznych, co także ma potwierdzenie w danych historycznych — zalewają miasta, infrastrukturę i rolnictwo.
Huragany i sztormy jako kolejne źródła ogromnych strat, co obserwujemy głównie w regionach przybrzeżnych.
Dalsza analiza mogłaby obejmować standaryzację nazw zdarzeń w
kolumnie EVTYPE oraz analizę przestrzenną rozkładu zdarzeń.
Dane mogą być również filtrowane pod kątem lat, aby przeanalizować
trendy czasowe.