crime <- read.csv("D:/ngongulaptrinh/Chicage Crime Data.csv")

1.Kiểm tra tổng quan

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

2.Làm sạch & chuẩn hóa cột ngày/giờ

🧠 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…
Dòng lệnh | Ý nghĩa
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 DateUpdated.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

3.Tạo các biến thời gian chi tiết và buổi (AM/PM)

# 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
Dòng code | Giải thích chi tiết
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.
- Sau đó 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.

kiểm tra các cột

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

4.Kiểm tra và xử lý dữ liệu bị thiếu (NA)

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
Mã lệnh | Ý nghĩa
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. |

5. Xóa tất cả các hàng có giá trị NA

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

6.Kiểm tra và xử lý dữ liệu trùng lặp

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  
##                    
##                    
##                    
##