crime <- read.csv("D:/ngongulaptrinh/Chicage Crime Data.csv")
dim(crime) # số dòng và cột
## [1] 1048575 22
str(crime) # cấu trúc dữ liệu
## 'data.frame': 1048575 obs. of 22 variables:
## $ ID : int 5741943 25953 26038 13279676 13274752 1930689 13203321 13210088 13210004 13210062 ...
## $ Case.Number : chr "HN549294" "JE240540" "JE279849" "JG507211" ...
## $ Date : chr "08/25/2007 09:22:18 AM" "05/24/2021 03:06:00 PM" "06/26/2021 09:24:00 AM" "11/09/2023 7:30" ...
## $ Block : chr "074XX N ROGERS AVE" "020XX N LARAMIE AVE" "062XX N MC CORMICK RD" "019XX W BYRON ST" ...
## $ IUCR : chr "560" "110" "110" "620" ...
## $ Primary.Type : chr "ASSAULT" "HOMICIDE" "HOMICIDE" "BURGLARY" ...
## $ Description : chr "SIMPLE" "FIRST DEGREE MURDER" "FIRST DEGREE MURDER" "UNLAWFUL ENTRY" ...
## $ Location.Description: chr "OTHER" "STREET" "PARKING LOT" "APARTMENT" ...
## $ Arrest : logi FALSE TRUE TRUE FALSE TRUE TRUE ...
## $ Domestic : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
## $ Beat : int 2422 2515 1711 1922 632 512 122 1225 333 1732 ...
## $ District : int 24 25 17 19 6 5 1 12 3 17 ...
## $ Ward : int 49 36 50 47 6 NA 42 27 7 30 ...
## $ Community.Area : int 1 19 13 5 44 NA 32 28 43 21 ...
## $ FBI.Code : chr "08A" "01A" "01A" "5" ...
## $ X.Coordinate : int NA 1141387 1152781 1162518 1183071 NA 1174694 1160870 1190812 1151117 ...
## $ Y.Coordinate : int NA 1913179 1941458 1925906 1847869 NA 1901831 1898642 1856743 1922554 ...
## $ Year : int 2007 2021 2021 2023 2023 2002 2023 2023 2023 2023 ...
## $ Updated.On : chr "08/17/2015 03:03:40 PM" "11/18/2023 03:39:49 PM" "11/18/2023 03:39:49 PM" "11/18/2023 03:39:49 PM" ...
## $ Latitude : num NA 41.9 42 42 41.7 ...
## $ Longitude : num NA -87.8 -87.7 -87.7 -87.6 ...
## $ Location : chr "" "(41.917838056, -87.755968972)" "(41.995219444, -87.713354912)" "(41.952345086, -87.677975059)" ...
👉 Nhận xét nhanh về kết quả:
Dữ liệu có 1,048,575 quan sát (dòng) và 22 biến (cột) — tức là một bộ dữ liệu khá lớn.
Các cột chính gồm:
🆔 , : định danh vụ án.IDCase.Number
📅 , , : thông tin thời gian.DateUpdated.OnYear
📍 , , , , : vị trí vụ việc.BlockDistrictCommunity.AreaLatitudeLongitude
🔎 Primary.Type, Description, FBI.Code: loại tội phạm.
🚓 , : đặc tính hành vi (bị bắt, bạo lực gia đình…).ArrestDomestic
🧠 Mục tiêu
Chuyển cột và từ chuỗi ký tự (chr) → kiểu thời gian (POSIXct) để ta dễ:DateUpdated.On
Lọc theo năm, tháng, hoặc giờ.
Tính toán số vụ theo ngày/tuần/tháng.
Vẽ biểu đồ xu hướng theo thời gian.
library(lubridate)
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
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
# Sao lưu từ bản gốc đã tạo
crime_a <- crime
# Chuyển đổi ngày và giờ - hỗ trợ nhiều định dạng cùng lúc
crime_a <- crime_a %>%
mutate(
Date = parse_date_time(Date, orders = c("mdy HMS p", "mdy HM", "mdy H p", "mdy")),
Updated.On = parse_date_time(Updated.On, orders = c("mdy HMS p", "mdy HM", "mdy"))
)
# Tạo thêm các cột thời gian hữu ích
crime_a <- crime_a %>%
mutate(
Year_Reported = year(Date),
Month = month(Date, label = TRUE, abbr = TRUE),
Weekday = wday(Date, label = TRUE, abbr = TRUE),
Hour = hour(Date)
)
# Kiểm tra lại kết quả
glimpse(crime_a[, c("Date", "Updated.On", "Year_Reported", "Month", "Weekday", "Hour")])
## Rows: 1,048,575
## Columns: 6
## $ Date <dttm> 2007-08-25 09:22:18, 2021-05-24 15:06:00, 2021-06-26 09…
## $ Updated.On <dttm> 2015-08-17 15:03:40, 2023-11-18 15:39:49, 2023-11-18 15…
## $ Year_Reported <dbl> 2007, 2021, 2021, 2023, 2023, 2002, 2023, 2023, 2023, 20…
## $ Month <ord> Thg8, Thg5, Thg6, Thg11, Thg11, Thg1, Thg9, Thg8, Thg7, …
## $ Weekday <ord> T7, T2, T7, T5, CN, T7, T4, T5, T2, CN, T2, T3, T2, CN, …
## $ Hour <int> 9, 15, 9, 7, 7, 21, 17, 12, 21, 7, 21, 14, 16, 10, 7, 14…
parse_date_time()
| Hàm linh hoạt
hơn mdy_hms()
. Nó sẽ thử nhiều định dạng
cùng lúc (trong orders
) để đọc được tất cả chuỗi ngày–giờ.
|orders = c("mdy HMS p", "mdy HM", "mdy H p", "mdy")
| Cho
phép R hiểu 4 kiểu định dạng khác nhau: có hoặc không có giây, có hoặc
không có AM/PM. |mutate()
| Gán lại cột Date
và
Updated.On
với kiểu thời gian thật (POSIXct
).
|Year_Reported
, Month
, Weekday
,
Hour
| Tách các thành phần thời gian để bạn dễ phân tích
thống kê (ví dụ: tội phạm theo tháng, theo thứ, theo giờ). |glimpse()
| Xem nhanh cấu trúc và 6 cột quan trọng sau khi
xử lý. |sum(is.na(crime_a$Date))
## [1] 0
# Nạp gói
library(dplyr)
library(lubridate)
# Đặt lại locale để tránh lỗi tiếng Việt khi hiển thị tháng
Sys.setlocale("LC_TIME", "C") # hoặc "English_United States"
## [1] "C"
# Chuẩn hóa cột Date và tách các thành phần thời gian
crime_a <- crime_a %>%
mutate(
# Chuyển Date sang định dạng dmy hms có AM/PM
Date = dmy_hms(format(Date, "%d/%m/%Y %I:%M:%S %p")),
# Trích xuất các thành phần từ Date
Year = year(Date),
Month = month(Date, label = TRUE, abbr = FALSE), # Tháng (January, February, …)
Day = day(Date),
Hour = hour(Date),
Minute = minute(Date),
Second = second(Date),
# Xác định thời điểm AM hay PM
Period = if_else(Hour < 12, "AM", "PM")
)
# Kiểm tra kết quả
crime_a %>%
select(Date, Year, Month, Day, Hour, Minute, Second, Period) %>%
head(10)
## Date Year Month Day Hour Minute Second Period
## 1 2007-08-25 09:22:18 2007 August 25 9 22 18 AM
## 2 2021-05-24 15:06:00 2021 May 24 15 6 0 PM
## 3 2021-06-26 09:24:00 2021 June 26 9 24 0 AM
## 4 2023-11-09 07:30:00 2023 November 9 7 30 0 AM
## 5 2023-11-12 07:59:00 2023 November 12 7 59 0 AM
## 6 2002-01-05 21:24:00 2002 January 5 21 24 0 PM
## 7 2023-09-06 17:00:00 2023 September 6 17 0 0 PM
## 8 2023-08-31 12:00:00 2023 August 31 12 0 0 PM
## 9 2023-07-24 21:45:00 2023 July 24 21 45 0 PM
## 10 2023-08-27 07:00:00 2023 August 27 7 0 0 AM
crime_a <- crime_a %>% mutate(...)
| Dùng
%>%
(pipe) để chuyển dữ liệu từ crime_a vào
mutate(). mutate()
giúp tạo hoặc thay đổi
cột mới trong khung dữ liệu. |Date = dmy_hms(format(Date, "%d/%m/%Y %I:%M:%S %p"))
| -
format()
chuyển cột Date
về chuỗi ký
tự có dạng ngày/tháng/năm giờ:phút:giây AM/PM
.
%d
= ngày, %m
= tháng, %Y
= năm, %I
= giờ (1–12), %p
= AM/PM. dmy_hms()
biến chuỗi đó lại thành kiểu thời gian
chuẩn POSIXct. |Year = year(Date)
| Tạo cột Year
chứa
năm (vd: 2023). |Month = month(Date, label = TRUE, abbr = FALSE)
| Tạo cột
Month
chứa tên tháng đầy đủ (vd: “Tháng
5”), nhờ label=TRUE
. |Day = day(Date)
| Lấy ngày trong tháng
(vd: 17). |Hour = hour(Date)
| Lấy giờ (0–23) từ cột
Date
. |Minute = minute(Date)
| Lấy phút. |Second = second(Date)
| Lấy giây. |Period = if_else(Hour < 12, "AM", "PM")
| Tạo thêm cột
buổi sáng hay chiều, dựa trên giá trị của
Hour
. Nếu nhỏ hơn 12 thì AM, ngược lại PM.crime_a %>%
select(Date, Year, Month, Day, Hour, Minute, Second, Period) %>%
head(10)
## Date Year Month Day Hour Minute Second Period
## 1 2007-08-25 09:22:18 2007 August 25 9 22 18 AM
## 2 2021-05-24 15:06:00 2021 May 24 15 6 0 PM
## 3 2021-06-26 09:24:00 2021 June 26 9 24 0 AM
## 4 2023-11-09 07:30:00 2023 November 9 7 30 0 AM
## 5 2023-11-12 07:59:00 2023 November 12 7 59 0 AM
## 6 2002-01-05 21:24:00 2002 January 5 21 24 0 PM
## 7 2023-09-06 17:00:00 2023 September 6 17 0 0 PM
## 8 2023-08-31 12:00:00 2023 August 31 12 0 0 PM
## 9 2023-07-24 21:45:00 2023 July 24 21 45 0 PM
## 10 2023-08-27 07:00:00 2023 August 27 7 0 0 AM
library(dplyr)
library(tidyr)
# BƯỚC 4: KIỂM TRA GIÁ TRỊ BỊ THIẾU (NA)
# 1️⃣ Số hàng có ít nhất 1 giá trị bị thiếu
n_na_rows <- sum(!complete.cases(crime_a))
n_na_rows
## [1] 624569
# 5️⃣ Số hàng đầy đủ (không bị thiếu giá trị nào)
n_complete_rows <- sum(complete.cases(crime_a))
n_complete_rows
## [1] 424006
complete.cases(crime_a)
| Trả về TRUE
nếu hàng
không có giá trị NA, ngược lại là FALSE
.
|!complete.cases(crime_a)
| Dấu !
đảo ngược kết
quả → TRUE
cho những hàng có ít nhất 1 NA.
|sum(!complete.cases(crime_a))
| Đếm xem có bao nhiêu hàng
chứa NA. |colSums(is.na(crime_a))
| Đếm tổng số NA trong mỗi
cột. |sort(decreasing = TRUE)
| Sắp xếp kết quả giảm dần để dễ
thấy cột nào thiếu nhiều nhất. |colMeans(is.na(crime_a))*100
| Tính tỷ lệ phần trăm
NA theo cột. |round(..., 3)
| Làm tròn kết quả đến 3 chữ số thập phân.
|crime_a <- crime_a %>%
drop_na()
# Kiểm tra lại xem còn NA không
sum(!complete.cases(crime_a))
## [1] 0
nrow(crime_a)
## [1] 424006
library(dplyr)
library(tidyr)
# 1. Kiểm tra số hàng trùng hoàn toàn
duplicates_count <- crime_a %>%
duplicated() %>%
sum()
duplicates_count # xem có bao nhiêu hàng trùng
## [1] 0
# 2. Nếu muốn xem nội dung các hàng trùng
crime_a %>%
filter(duplicated(.))
## [1] ID Case.Number Date
## [4] Block IUCR Primary.Type
## [7] Description Location.Description Arrest
## [10] Domestic Beat District
## [13] Ward Community.Area FBI.Code
## [16] X.Coordinate Y.Coordinate Year
## [19] Updated.On Latitude Longitude
## [22] Location Year_Reported Month
## [25] Weekday Hour Day
## [28] Minute Second Period
## <0 rows> (or 0-length row.names)
# 3. Nếu muốn loại bỏ các hàng trùng
crime_a <- crime_a %>%
distinct()
# 4. Kiểm tra lại xem còn trùng không
sum(duplicated(crime_a))
## [1] 0
#u 7.Khám phá dữ liệu (EDA) Mục tiêu
Hiểu dữ liệu của bạn sau khi đã làm sạch:
Có bao nhiêu dòng và biến?
Các loại tội phạm nào phổ biến nhất?
Khi nào tội phạm thường xảy ra (giờ, ngày, tháng, năm)?
Phân bố theo khu vực (nếu có cột địa lý)?
glimpse(crime_a)
## Rows: 424,006
## Columns: 30
## $ ID <int> 25953, 26038, 13279676, 13274752, 13203321, 13210…
## $ Case.Number <chr> "JE240540", "JE279849", "JG507211", "JG501049", "…
## $ Date <dttm> 2021-05-24 15:06:00, 2021-06-26 09:24:00, 2023-1…
## $ Block <chr> "020XX N LARAMIE AVE", "062XX N MC CORMICK RD", "…
## $ IUCR <chr> "110", "110", "620", "454", "1320", "1153", "281"…
## $ Primary.Type <chr> "HOMICIDE", "HOMICIDE", "BURGLARY", "BATTERY", "C…
## $ Description <chr> "FIRST DEGREE MURDER", "FIRST DEGREE MURDER", "UN…
## $ Location.Description <chr> "STREET", "PARKING LOT", "APARTMENT", "SMALL RETA…
## $ Arrest <lgl> TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FAL…
## $ Domestic <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, …
## $ Beat <int> 2515, 1711, 1922, 632, 122, 1225, 333, 1732, 822,…
## $ District <int> 25, 17, 19, 6, 1, 12, 3, 17, 8, 8, 7, 22, 7, 9, 1…
## $ Ward <int> 36, 50, 47, 6, 42, 27, 7, 30, 14, 18, 6, 21, 17, …
## $ Community.Area <int> 19, 13, 5, 44, 32, 28, 43, 21, 63, 70, 69, 73, 67…
## $ FBI.Code <chr> "01A", "01A", "5", "08B", "14", "11", "2", "6", "…
## $ X.Coordinate <int> 1141387, 1152781, 1162518, 1183071, 1174694, 1160…
## $ Y.Coordinate <int> 1913179, 1941458, 1925906, 1847869, 1901831, 1898…
## $ Year <dbl> 2021, 2021, 2023, 2023, 2023, 2023, 2023, 2023, 2…
## $ Updated.On <dttm> 2023-11-18 15:39:49, 2023-11-18 15:39:49, 2023-1…
## $ Latitude <dbl> 41.91784, 41.99522, 41.95235, 41.73775, 41.88602,…
## $ Longitude <dbl> -87.75597, -87.71335, -87.67798, -87.60486, -87.6…
## $ Location <chr> "(41.917838056, -87.755968972)", "(41.995219444, …
## $ Year_Reported <dbl> 2021, 2021, 2023, 2023, 2023, 2023, 2023, 2023, 2…
## $ Month <ord> May, June, November, November, September, August,…
## $ Weekday <ord> T2, T7, T5, CN, T4, T5, T2, CN, T2, T3, T2, CN, T…
## $ Hour <int> 15, 9, 7, 7, 17, 12, 21, 7, 21, 14, 16, 10, 7, 14…
## $ Day <int> 24, 26, 9, 12, 6, 31, 24, 27, 4, 15, 24, 3, 17, 2…
## $ Minute <int> 6, 24, 30, 59, 0, 0, 45, 0, 30, 20, 9, 27, 0, 27,…
## $ Second <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ Period <chr> "PM", "AM", "AM", "AM", "PM", "PM", "PM", "AM", "…
summary(crime_a)
## ID Case.Number Date
## Min. : 634 Length:424006 Min. :2001-01-01 00:00:00
## 1st Qu.: 2212479 Class :character 1st Qu.:2002-07-04 15:44:15
## Median : 2346379 Mode :character Median :2002-09-29 20:55:11
## Mean : 7020881 Mean :2012-03-24 04:51:54
## 3rd Qu.:13309356 3rd Qu.:2023-12-11 21:30:00
## Max. :13470717 Max. :2024-05-20 00:00:00
##
## Block IUCR Primary.Type Description
## Length:424006 Length:424006 Length:424006 Length:424006
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
##
## Location.Description Arrest Domestic Beat
## Length:424006 Mode :logical Mode :logical Min. : 111
## Class :character FALSE:332686 FALSE:349814 1st Qu.: 621
## Mode :character TRUE :91320 TRUE :74192 Median :1112
## Mean :1190
## 3rd Qu.:1811
## Max. :2535
##
## District Ward Community.Area FBI.Code
## Min. : 1.00 Min. : 1.00 Min. : 0.00 Length:424006
## 1st Qu.: 6.00 1st Qu.:10.00 1st Qu.:22.00 Class :character
## Median :10.00 Median :22.00 Median :32.00 Mode :character
## Mean :11.37 Mean :22.76 Mean :36.83
## 3rd Qu.:17.00 3rd Qu.:34.00 3rd Qu.:56.00
## Max. :31.00 Max. :50.00 Max. :77.00
##
## X.Coordinate Y.Coordinate Year
## Min. : 0 Min. : 0 Min. :2001
## 1st Qu.:1153671 1st Qu.:1859962 1st Qu.:2002
## Median :1166400 Median :1891752 Median :2002
## Mean :1164889 Mean :1886712 Mean :2012
## 3rd Qu.:1176417 3rd Qu.:1910180 3rd Qu.:2023
## Max. :1205119 Max. :1951503 Max. :2024
##
## Updated.On Latitude Longitude
## Min. :2006-03-31 22:03:38 Min. :36.62 Min. :-91.69
## 1st Qu.:2018-02-28 15:56:25 1st Qu.:41.77 1st Qu.:-87.71
## Median :2018-02-28 15:56:25 Median :41.86 Median :-87.66
## Mean :2020-12-04 20:44:34 Mean :41.84 Mean :-87.67
## 3rd Qu.:2023-12-26 15:41:46 3rd Qu.:41.91 3rd Qu.:-87.63
## Max. :2024-05-27 15:41:20 Max. :42.02 Max. :-87.52
##
## Location Year_Reported Month Weekday
## Length:424006 Min. :2001 May : 56547 CN:59751
## Class :character 1st Qu.:2002 July : 46840 T2:59501
## Mode :character Median :2002 September: 45451 T3:59868
## Mean :2012 August : 45193 T4:60663
## 3rd Qu.:2023 June : 43657 T5:60281
## Max. :2024 April : 34953 T6:62520
## (Other) :151365 T7:61422
## Hour Day Minute Second
## Min. : 0.00 Min. : 1.00 Min. : 0.00 Min. : 0.00
## 1st Qu.: 8.00 1st Qu.: 8.00 1st Qu.: 0.00 1st Qu.: 0.00
## Median :14.00 Median :15.00 Median :19.00 Median : 0.00
## Mean :12.86 Mean :15.61 Mean :20.22 Mean : 1.88
## 3rd Qu.:19.00 3rd Qu.:23.00 3rd Qu.:34.00 3rd Qu.: 0.00
## Max. :23.00 Max. :31.00 Max. :59.00 Max. :59.00
##
## Period
## Length:424006
## Class :character
## Mode :character
##
##
##
##