library(tidyverse)
library(dplyr)
library(ggplot2)
library(readxl)
d <- read_excel("C:/Users/hoang/Downloads/US_Accidents_March23_reduced_500k_pd.xlsx")
Bộ dữ liệu về US_Accidents gồm có 500.001 dữ liệu, trong đó có các biến (Mã định danh duy nhất cho mỗi vụ tai nạn, Nguồn thu thập dữ liệu, Mức độ nghiêm trọng của tai nạn (1–4), Vĩ độ, Kinh độ, Tên đường, Thành phố, Quận, Bang, Mã bưu điện, Quốc gia, Mã sân bay, Nhiệt độ, Độ ẩm, Áp suất khí quyển, Tầm nhìn, Hướng gió, Tốc độ gió, Tình trạng thời tiết).
dim(d)
## [1] 500001 19
Bộ dữ liệu có 500001 quan sát và 19 biến
str(d)
## tibble [500,001 × 19] (S3: tbl_df/tbl/data.frame)
## $ ID : chr [1:500001] "A-1" "A-2" "A-3" "A-4" ...
## $ Source : chr [1:500001] "Source2" "Source2" "Source2" "Source2" ...
## $ Severity : num [1:500001] 3 2 2 3 2 3 2 3 2 3 ...
## $ Start_Lat : num [1:500001] 39.9 39.9 39.1 39.7 39.6 ...
## $ Start_Lng : num [1:500001] -84.1 -82.8 -84 -84.2 -84.2 ...
## $ Street : chr [1:500001] "I-70 E" "Brice Rd" "State Route 32" "I-75 S" ...
## $ City : chr [1:500001] "Dayton" "Reynoldsburg" "Williamsburg" "Dayton" ...
## $ County : chr [1:500001] "Montgomery" "Franklin" "Clermont" "Montgomery" ...
## $ State : chr [1:500001] "OH" "OH" "OH" "OH" ...
## $ Zipcode : chr [1:500001] "45424" "43068-3402" "45176" "45417" ...
## $ Country : chr [1:500001] "US" "US" "US" "US" ...
## $ Airport_Code : chr [1:500001] "KFFO" "KCMH" "KI69" "KDAY" ...
## $ Temperature(F) : num [1:500001] 36.9 37.9 36 35.1 36 37.9 34 34 33.3 37.4 ...
## $ Humidity(%) : num [1:500001] 91 100 100 96 89 97 100 100 99 100 ...
## $ Pressure(in) : num [1:500001] 29.7 29.6 29.7 29.6 29.6 ...
## $ Visibility(mi) : num [1:500001] 10 10 10 9 6 7 7 7 5 3 ...
## $ Wind_Direction : chr [1:500001] "Calm" "Calm" "SW" "SW" ...
## $ Wind_Speed(mph) : num [1:500001] 4.6 1.2 3.5 4.6 3.5 3.5 3.5 3.5 1.2 4.6 ...
## $ Weather_Condition: chr [1:500001] "Light Rain" "Light Rain" "Overcast" "Mostly Cloudy" ...
Bộ dữ liệu có 500.001 quan sát và 19 biến.
Các biến bao gồm thông tin về địa điểm (thành phố, tiểu bang, tọa độ), điều kiện thời tiết (nhiệt độ, độ ẩm, áp suất, tầm nhìn, hướng gió, tốc độ gió) và mức độ nghiêm trọng của tai nạn (Severity).
Dữ liệu gồm cả biến định tính (chuỗi ký tự như City, State, Weather_Condition) và biến định lượng (các giá trị số như Temperature, Humidity, Pressure).
Nhìn chung, cấu trúc dữ liệu đầy đủ, phù hợp để thực hiện các bước xử lý, phân tổ và phân tích thống kê tiếp theo.
names(d)
## [1] "ID" "Source" "Severity"
## [4] "Start_Lat" "Start_Lng" "Street"
## [7] "City" "County" "State"
## [10] "Zipcode" "Country" "Airport_Code"
## [13] "Temperature(F)" "Humidity(%)" "Pressure(in)"
## [16] "Visibility(mi)" "Wind_Direction" "Wind_Speed(mph)"
## [19] "Weather_Condition"
data.frame(
Variable = c("ID","Severity","Start_Lat","Start_Lng","Street","City","County","State","Zipcode","Country","Airport_Code","Temperature(F)","Humidity(%)","Pressure(in)","Visibility(mi)","Wind_Direction","Wind_Speed(mph)","Weather_Condition"),
Meaning = c("Mã định danh duy nhất cho từng vụ tai nạn",
"Mức độ nghiêm trọng của vụ tai nạn (1 = nhẹ nhất, 4 = nghiêm trọng nhất)",
"Vĩ độ nơi bắt đầu vụ tai nạn (Latitude)",
"Kinh độ nơi bắt đầu vụ tai nạn (Longitude)",
"Tên con đường xảy ra tai nạn",
"Thành phố nơi tai nạn được ghi nhận",
"Hạt (County) quản lý khu vực xảy ra tai nạn",
"Bang (State) nơi xảy ra tai nạn (ký hiệu 2 chữ viết tắt)",
"Mã bưu chính của khu vực tai nạn",
"Quốc gia xảy ra tai nạn (thường là US)",
"Mã sân bay gần nhất (tham chiếu vị trí tai nạn)",
"Nhiệt độ (độ F) tại thời điểm tai nạn",
"Độ ẩm không khí (%) tại thời điểm tai nạn",
"Áp suất khí quyển (inch thủy ngân)",
"Tầm nhìn của tài xế (mile)",
"Hướng gió tại thời điểm tai nạn (ví dụ: N, SW, E...)",
"Tốc độ gió (mile/giờ)",
"Điều kiện thời tiết (ví dụ: Rain, Clear, Fog, Snow...)"),
stringsAsFactors = FALSE)
summary(d)
## ID Source Severity Start_Lat
## Length:500001 Length:500001 Min. :1.000 Min. :25.43
## Class :character Class :character 1st Qu.:2.000 1st Qu.:32.81
## Mode :character Mode :character Median :2.000 Median :34.25
## Mean :2.375 Mean :35.93
## 3rd Qu.:3.000 3rd Qu.:40.13
## Max. :4.000 Max. :48.20
##
## Start_Lng Street City County
## Min. :-123.81 Length:500001 Length:500001 Length:500001
## 1st Qu.:-118.10 Class :character Class :character Class :character
## Median : -95.54 Mode :character Mode :character Mode :character
## Mean : -97.59
## 3rd Qu.: -81.57
## Max. : -70.57
##
## State Zipcode Country Airport_Code
## Length:500001 Length:500001 Length:500001 Length:500001
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
##
## Temperature(F) Humidity(%) Pressure(in) Visibility(mi)
## Min. :-77.80 Min. : 4.00 Min. : 0.12 Min. : 0.000
## 1st Qu.: 55.00 1st Qu.: 49.00 1st Qu.:29.90 1st Qu.: 10.000
## Median : 66.20 Median : 66.00 Median :30.00 Median : 10.000
## Mean : 64.67 Mean : 64.53 Mean :30.00 Mean : 9.228
## 3rd Qu.: 77.00 3rd Qu.: 82.00 3rd Qu.:30.11 3rd Qu.: 10.000
## Max. :161.60 Max. :100.00 Max. :33.04 Max. :111.000
## NA's :7237 NA's :7902 NA's :5730 NA's :10530
## Wind_Direction Wind_Speed(mph) Weather_Condition
## Length:500001 Min. : 0.00 Length:500001
## Class :character 1st Qu.: 5.80 Class :character
## Mode :character Median : 8.10 Mode :character
## Mean : 8.91
## 3rd Qu.: 11.50
## Max. :822.80
## NA's :89030
Kết quả thống kê mô tả cho thấy bộ dữ liệu có các biến định lượng như Severity, Temperature(F), Humidity(%), Pressure(in), Visibility(mi), Wind_Speed(mph) và nhiều biến định tính về địa điểm, thời tiết.
Mức độ nghiêm trọng (Severity) dao động từ 1-4, với giá trị trung bình khoảng 2,37. Cho thấy phần lớn các vụ tai nạn có mức độ trung bình.
Nhiệt độ trung bình khoảng 64,7°F, dao động khá rộng từ -77,8°F đến 161,6°F, thể hiện dữ liệu thu thập trên nhiều vùng khí hậu khác nhau.
Độ ẩm trung bình khoảng 64,5%, cao nhất là 100%.
Áp suất trung bình quanh mức 30 inHg, trong khoảng hợp lý của điều kiện khí quyển thông thường.
Tầm nhìn (Visibility) chủ yếu quanh 10 dặm, nhưng có giá trị cực đại bất thường 111 dặm, có thể là ngoại lệ.
Tốc độ gió trung bình 8,9 mph, tuy nhiên có giá trị lớn nhất 822,8 mph, nhiều khả năng là dữ liệu lỗi cần xử lý.
Một số biến như Temperature(F), Humidity(%), Pressure(in), Visibility(mi), Wind_Speed(mph) có giá trị bị thiếu (NA).
Nhìn chung, dữ liệu có phân bố hợp lý, nhưng cần xử lý giá trị thiếu và loại bỏ các giá trị ngoại lai trước khi phân tích tiếp theo.
colSums(is.na(d))
## ID Source Severity Start_Lat
## 0 0 0 0
## Start_Lng Street City County
## 0 0 22 0
## State Zipcode Country Airport_Code
## 0 58 0 60
## Temperature(F) Humidity(%) Pressure(in) Visibility(mi)
## 7237 7902 5730 10530
## Wind_Direction Wind_Speed(mph) Weather_Condition
## 4139 89030 10176
Kết quả kiểm tra giá trị khuyết cho thấy bộ dữ liệu có một số biến chứa nhiều giá trị bị thiếu (NA).
Các biến City, Zipcode, Airport_Code có một lượng nhỏ giá trị thiếu, dao động từ 22 đến 60 dòng, không đáng kể so với toàn bộ dữ liệu.
Tuy nhiên, các biến Temperature(F), Humidity(%), Pressure(in), Visibility(mi), Wind_Direction, Wind_Speed(mph), Weather_Condition có số lượng NA rất lớn (từ 4.000 đến gần 90.000 giá trị).
→ Điều này cho thấy dữ liệu thời tiết còn thiếu sót đáng kể, có thể do không thu thập được tại một số vị trí hoặc thời điểm.
→ Cần xử lý giá trị thiếu bằng cách xoá những dòng có NA trước khi tiến hành phân tích hoặc xây dựng mô hình thống kê.
ds <- na.omit(d)
sum(duplicated(ds))
## [1] 0
Vậy không có giá trị nào trùng lặp
ds <- ds %>%
mutate(Temp_Group = cut(`Temperature(F)`,
breaks = c(-Inf, 32, 60, 80, Inf),
labels = c("Lạnh", "Mát", "Ấm", "Nóng")))
table(ds$Temp_Group)
##
## Lạnh Mát Ấm Nóng
## 19339 112847 186719 86449
Nhóm “Ấm” (60–80°F) chiếm số vụ tai nạn cao nhất, cho thấy phần lớn tai nạn xảy ra trong điều kiện thời tiết dễ chịu và phổ biến — có thể vì đây là thời điểm có lưu lượng xe cao nhất (186719 vụ tai nạn).
Nhóm “Mát” (32–60°F) đứng thứ hai (112834 vụ tai nạn), cũng phản ánh điều kiện thời tiết thuận lợi cho việc di chuyển.
Nhóm “Nóng” (>80°F) chiếm tỷ lệ trung bình (86449 vụ tai nạn), có thể do ảnh hưởng của nhiệt độ cao làm giảm khả năng tập trung của tài xế.
Nhóm “Lạnh” (<32°F) có ít vụ tai nạn nhất (19339 vụ tai nạn), có thể vì ít phương tiện lưu thông trong điều kiện lạnh giá hoặc người dân hạn chế di chuyển.
ds <- ds %>%
mutate(Humi_Group = cut(`Humidity(%)`,
breaks = c(-Inf, 40, 70, Inf),
labels = c("Thấp", "Vừa", "Cao")))
table(ds$Humi_Group)
##
## Thấp Vừa Cao
## 63881 182722 158751
Kết quả phân loại độ ẩm cho thấy phần lớn các vụ tai nạn xảy ra trong điều kiện độ ẩm trung bình (40–70%), với 182.722 vụ, chiếm khoảng 44,5% tổng số quan sát.
Tiếp theo là nhóm độ ẩm cao (>70%) với 158.738 vụ (khoảng 38,7%), phản ánh rằng khi độ ẩm tăng cao — thường kèm theo mưa hoặc sương mù — nguy cơ tai nạn vẫn đáng kể.
Ngược lại, nhóm độ ẩm thấp (<40%) chỉ ghi nhận 63.881 vụ (tương đương 15,6%) — mức thấp nhất, cho thấy điều kiện thời tiết khô ráo, tầm nhìn tốt giúp giảm rủi ro xảy ra tai nạn.
ds <- ds %>%
mutate(Weather_Simple = case_when(
str_detect(Weather_Condition, "Rain|Thunderstorm") ~ "Mưa",
str_detect(Weather_Condition, "Snow|Sleet") ~ "Tuyết",
str_detect(Weather_Condition, "Fog|Mist") ~ "Sương mù",
str_detect(Weather_Condition, "Clear|Fair") ~ "Trời quang",
str_detect(Weather_Condition, "Cloud|Overcast") ~ "Nhiều mây",
TRUE ~ "Khác"
))
table(ds$Weather_Simple)
##
## Khác Mưa Nhiều mây Sương mù Tuyết Trời quang
## 5552 25884 206798 1230 4182 161708
Kết quả cho thấy phần lớn các vụ tai nạn xảy ra trong nhóm “Khác” với 370.110 vụ, chiếm tỷ lệ áp đảo (trên 85%) — nhóm này chủ yếu bao gồm các điều kiện thời tiết bình thường hoặc không được ghi nhận rõ ràng.
Trong khi đó, điều kiện “Mưa” ghi nhận 25.875 vụ (khoảng 6%) — phản ánh rằng mặt đường trơn trượt và tầm nhìn kém có thể góp phần làm tăng rủi ro tai nạn.
Các điều kiện “Sương mù” (5.174 vụ, 1,2%) và “Tuyết” (4.182 vụ, 1%) có số lượng tương đối nhỏ, cho thấy các hiện tượng thời tiết cực đoan này ít xảy ra hơn, nhưng vẫn tiềm ẩn nguy hiểm cao khi xuất hiện.
ggplot(ds, aes(x = Temp_Group)) +
geom_bar(fill = "tomato") +
labs(title = "Phan bo nhiet do khi xay ra tai nan",
x = "Nhóm nhiet do",
y = "So luong vu tai nan")
ggplot(ds, aes(x = Humi_Group)) +
geom_bar(fill = "skyblue") +
labs(title = "Phan bo do am khi xay ra tai nan",
x = "Nhom do am",
y = "So luong vu tai nan")
ggplot(ds, aes(x = Weather_Simple)) +
geom_bar(fill = "orange") +
labs(title = "Phan bo theo thoi tiet khi xay ra tai nan",
x = "Nhom thoi tiet",
y = "So luong vu tai nann")