This is a data analysis project about storm data in the USA. The assignment mainly analyze the fatalities and injuries in different storms and the economic lost of properties and crops. I use dplyr package to make the analyzing steps more readable and easy to interpret. The results indicate that tornado, excessive heat, TSTM wind and flood are most harmful types with respect to population health, and flood, hurricane, tornado, storm surge, and hail make the top 4 greatest economic lost.
First of all, it’s necessary to set the right working directory. Then the data is downloaded from the link and can be read directly with function read.csv(). And we use str() to have a first look at the structure of the data.
setwd("C:/Users/Chunxiao Pan/Documents/R_Tutorial/Data_Science_Foundations_using_R_Specialization/ReproducibleData_Week4")
download.file("https://d396qusza40orc.cloudfront.net/repdata%2Fdata%2FStormData.csv.bz2", "./stormdata.csv.bz2")
stormdata <- read.csv("stormdata.csv.bz2")
str(stormdata)
## 'data.frame': 902297 obs. of 37 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" ...
## $ BGN_RANGE : num 0 0 0 0 0 0 0 0 0 0 ...
## $ BGN_AZI : chr "" "" "" "" ...
## $ BGN_LOCATI: chr "" "" "" "" ...
## $ END_DATE : chr "" "" "" "" ...
## $ END_TIME : chr "" "" "" "" ...
## $ COUNTY_END: num 0 0 0 0 0 0 0 0 0 0 ...
## $ COUNTYENDN: logi NA NA NA NA NA NA ...
## $ END_RANGE : num 0 0 0 0 0 0 0 0 0 0 ...
## $ END_AZI : chr "" "" "" "" ...
## $ END_LOCATI: chr "" "" "" "" ...
## $ LENGTH : num 14 2 0.1 0 0 1.5 1.5 0 3.3 2.3 ...
## $ WIDTH : num 100 150 123 100 150 177 33 33 100 100 ...
## $ F : int 3 2 2 2 2 2 2 1 3 3 ...
## $ MAG : num 0 0 0 0 0 0 0 0 0 0 ...
## $ FATALITIES: num 0 0 0 0 0 0 0 0 1 0 ...
## $ INJURIES : num 15 0 2 2 2 6 1 0 14 0 ...
## $ PROPDMG : num 25 2.5 25 2.5 2.5 2.5 2.5 2.5 25 25 ...
## $ PROPDMGEXP: chr "K" "K" "K" "K" ...
## $ CROPDMG : num 0 0 0 0 0 0 0 0 0 0 ...
## $ CROPDMGEXP: chr "" "" "" "" ...
## $ WFO : chr "" "" "" "" ...
## $ STATEOFFIC: chr "" "" "" "" ...
## $ ZONENAMES : chr "" "" "" "" ...
## $ LATITUDE : num 3040 3042 3340 3458 3412 ...
## $ LONGITUDE : num 8812 8755 8742 8626 8642 ...
## $ LATITUDE_E: num 3051 0 0 0 0 ...
## $ LONGITUDE_: num 8806 0 0 0 0 ...
## $ REMARKS : chr "" "" "" "" ...
## $ REFNUM : num 1 2 3 4 5 6 7 8 9 10 ...
This part of the analysis involved calculating property and crop damage values by accounting for their respective exponents. For property damage, exponents were assigned to each level, and invalid data was excluded by assigning a value of ‘0’. The property damage value was then computed by multiplying the property damage and exponent values. A similar process was followed for crop damage, with the damage value calculated by multiplying the crop damage and crop exponent values, and invalid data excluded accordingly.
stormdata$PROPDMGEXP <- as.character(stormdata$PROPDMGEXP)
stormdata$PROPDMGEXP[is.na(stormdata$PROPDMGEXP)] <- 0
stormdata$PROPDMGEXP[!grepl("K|M|B", stormdata$PROPDMGEXP, ignore.case = TRUE)] <- 0
stormdata$PROPDMGEXP[grep("K", stormdata$PROPDMGEXP, ignore.case = TRUE)] <- "3"
stormdata$PROPDMGEXP[grep("M", stormdata$PROPDMGEXP, ignore.case = TRUE)] <- "6"
stormdata$PROPDMGEXP[grep("B", stormdata$PROPDMGEXP, ignore.case = TRUE)] <- "9"
stormdata$PROPDMGEXP <- as.numeric(as.character(stormdata$PROPDMGEXP))
stormdata$property.damage <- stormdata$PROPDMG * 10^stormdata$PROPDMGEXP
stormdata$CROPDMGEXP <- as.character(stormdata$CROPDMGEXP)
stormdata$CROPDMGEXP[is.na(stormdata$CROPDMGEXP)] <- 0
stormdata$CROPDMGEXP[!grepl("K|M|B", stormdata$CROPDMGEXP, ignore.case = TRUE)] <- 0
stormdata$CROPDMGEXP[grep("K", stormdata$CROPDMGEXP, ignore.case = TRUE)] <- "3"
stormdata$CROPDMGEXP[grep("M", stormdata$CROPDMGEXP, ignore.case = TRUE)] <- "6"
stormdata$CROPDMGEXP[grep("B", stormdata$CROPDMGEXP, ignore.case = TRUE)] <- "9"
stormdata$CROPDMGEXP <- as.numeric(as.character(stormdata$CROPDMGEXP))
stormdata$crop.damage <- stormdata$CROPDMG * 10^stormdata$CROPDMGEXP
Calculate the fatalities and injuries within different types of events, and calculate the total numbers and arrange them in a descending order. dplyr package is very useful and the code is neat and precise.
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.3.3
##
## 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
fatalData <- stormdata%>%
group_by(EVTYPE)%>%
summarize(fatalities=sum(FATALITIES,na.rm = T))%>%
arrange(desc(fatalities))
fatalData <- fatalData[1:10,]
injuriesData <- stormdata%>%
group_by(EVTYPE)%>%
summarize(injuries=sum(INJURIES,na.rm = T))%>%
arrange(desc(injuries))
injuriesData <- injuriesData[1:10,]
Use ggplot to visualize the data of fatalities and injuries. When making the bar plot, pay attention to the reorder(), it’s useful to order the bars in a nice order.
library(ggplot2)
ggplot(fatalData, aes(reorder(EVTYPE,-fatalities), fatalities))+
geom_bar(stat = "identity", width = NULL)+
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
xlab("Event Type") + ylab("Fatalities")
ggplot(injuriesData, aes(reorder(EVTYPE,-injuries), injuries))+
geom_bar(stat = "identity", width = NULL)+
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
xlab("Event Type") + ylab("Injuries")
Calculate the property damage in USD and crop damage in USD repectively within different types of events, and calculate the total numbers and arrange them in a descending order to find the top 10 most harmful types.
economiclost <- stormdata %>%
select(EVTYPE,property.damage:crop.damage)%>%
group_by(EVTYPE)%>%
summarize(PropertyDamage_USD=sum(property.damage),CropDamage_USD=sum(crop.damage))%>%
arrange(desc(PropertyDamage_USD),desc(CropDamage_USD))%>%
print(n=10)
## # A tibble: 985 × 3
## EVTYPE PropertyDamage_USD CropDamage_USD
## <chr> <dbl> <dbl>
## 1 FLOOD 144657709807 5661968450
## 2 HURRICANE/TYPHOON 69305840000 2607872800
## 3 TORNADO 56937160779. 414953270
## 4 STORM SURGE 43323536000 5000
## 5 FLASH FLOOD 16140812067. 1421317100
## 6 HAIL 15732267048. 3025954473
## 7 HURRICANE 11868319010 2741910000
## 8 TROPICAL STORM 7703890550 678346000
## 9 WINTER STORM 6688497251 26944000
## 10 HIGH WIND 5270046295 638571300
## # ℹ 975 more rows
Sum up the property damage in USD and crop damage in USD within different types of events, and calculate the total numbers and arrange them in a descending order to find the top 10 most harmful types. This plot is to showcase the economic lost of 10 types of events. The values are too big, so we change the unit into millions(by dividing the data by 10^6)
library(ggplot2)
economiclost <- economiclost %>%
mutate(total_lost_USD=PropertyDamage_USD+CropDamage_USD)%>%
arrange(desc(total_lost_USD))
economiclost <- economiclost[1:10,]
ggplot(economiclost, aes(reorder(EVTYPE,-total_lost_USD), total_lost_USD/10^6))+
geom_bar(stat = "identity", width = NULL)+
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
xlab("Event Type") + ylab("Total Lost in USD (millions)")
#Conclusion The results of this analysis highlight the substantial impact that weather events have on public health and the economy in the United States. Understanding the types of events that cause the most harm can help inform disaster preparedness and resource allocation efforts to better protect communities and reduce the negative consequences of these events.