Bài 1

Khám bệnh cho dữ liệu thô

Nhiệm vụ:

  • Cài đặt và tải các gói thư viện pacman, rio, tidyverse.
if (!require("pacman")) install.packages("pacman")
pacman::p_load(rio, tidyverse)
  • Dùng hàm rio::import() để nạp file dữ liệu vào.
df_raw <- rio::import("raw_health_survey.csv")
  • Dùng hàm summary() và glimpse() để kiểm tra tổng quan.
summary(df_raw)
##        ID              Age            Gender            Heart_Rate    
##  Min.   :  1.00   Min.   :  0.00   Length:250         Min.   : 50.00  
##  1st Qu.: 63.25   1st Qu.: 37.25   Class :character   1st Qu.: 68.50  
##  Median :125.50   Median : 46.00   Mode  :character   Median : 76.00  
##  Mean   :125.50   Mean   : 56.60                      Mean   : 75.86  
##  3rd Qu.:187.75   3rd Qu.: 53.00                      3rd Qu.: 82.50  
##  Max.   :250.00   Max.   :999.00                      Max.   :106.00  
##                                                       NA's   :15      
##      Weight          Income         
##  Min.   : 17.70   Length:250        
##  1st Qu.: 54.70   Class :character  
##  Median : 65.35   Mode  :character  
##  Mean   : 66.04                     
##  3rd Qu.: 76.58                     
##  Max.   :103.20                     
##  NA's   :20
glimpse(df_raw)
## Rows: 250
## Columns: 6
## $ ID         <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, …
## $ Age        <int> 51, 32, 47, 44, 37, 15, 36, 33, 46, 39, 40, 999, 42, 42, 14…
## $ Gender     <chr> "nam", "nu", "1", "0", "nam", "Female", "F", "0", "M", "nu"…
## $ Heart_Rate <int> 73, 80, 61, 71, 83, 76, 78, 62, 80, 70, 58, 81, 75, 68, 78,…
## $ Weight     <dbl> 103.2, NA, 74.3, NA, 75.8, NA, NA, NA, 57.3, NA, NA, NA, NA…
## $ Income     <chr> "High", "Medium", "High", NA, "High", "Medium", "Medium", "…

[CẢM NGHĨ VÀ TƯ DUY CỦA BẠN] Câu hỏi: Từ kết quả summary(), bạn phát hiện ra những điểm bất thường (Outliers) nào vô lí về mặt sinh học? Ở biến Gender, bạn thấy người nhập liệu đã gây ra thảm họa gì? Trả lời: - Điểm bất thường sinh học: - Age: Min. = 0 Max. = 999 Mean = 56.60 Median = 46 - Weight: Min. = 17.70 Max. = 103.20 NA’s = 20

  • Thảm họa ở biến Gender: dữ liệu giới tính đã được nhập không thống nhất. Người nhập liệu đã dùng nhiều cách khác nhau để mô tả cùng một giới tính, bao gồm chữ tiếng Việt, chữ tiếng Anh, chữ viết tắt và cả mã số. Điều này làm cho cùng một nhóm đối tượng bị chia thành nhiều nhóm khác nhau, gây khó khăn cho việc thống kê và phân tích.
unique(df_raw$Gender)
## [1] "nam"    "nu"     "1"      "0"      "Female" "F"      "M"      "Male"

Bài 2

Làm sạch dữ liệu (Data Cleaning)

Nhiệm vụ:

  • Dùng ngữ pháp dplyr (mutate, filter, ifelse, case_when) để dọn dẹp.

  • Đổi các lỗi tuổi vô lí thành NA.

  • Đưa biến Gender về một chuẩn duy nhất là “Male” và “Female”.

  • Lưu tất cả vào một bảng dữ liệu mới tên là df_clean.

library(dplyr)
# Gọi 'dplyr' để làm sạch dữ liệu
df_clean <- df_raw %>%
  mutate(
# Dùng mutate để sửa thông tin trong 3 cột Age, Weight, Gender
    Age = ifelse(Age <= 0 | Age > 120, NA, Age),
# Đổi các tuổi <= 0 hoặc > 120 thành NA
    Weight = ifelse(Weight < 30,NA, Weight),
# Đổi các cân nặng < 30 thành NA
    Gender = case_when(
      Gender %in% c("M", "Male", "male", "nam", "1") ~ "Male",
      Gender %in% c("F", "Female", "female", "nu", "0") ~ "Female",
      TRUE ~ NA_character_
# Thống nhất giới tính lại thành chỉ có 2 giá trị là Male với Female
    )
  )

[CẢM NGHĨ VÀ TƯ DUY CỦA BẠN]

Câu hỏi: So sánh bảng dữ liệu trước và sau khi làm sạch, bạn cảm thấy thế nào về vai trò của việc mã hóa dữ liệu?

Trả lời:

summary(df_raw)
##        ID              Age            Gender            Heart_Rate    
##  Min.   :  1.00   Min.   :  0.00   Length:250         Min.   : 50.00  
##  1st Qu.: 63.25   1st Qu.: 37.25   Class :character   1st Qu.: 68.50  
##  Median :125.50   Median : 46.00   Mode  :character   Median : 76.00  
##  Mean   :125.50   Mean   : 56.60                      Mean   : 75.86  
##  3rd Qu.:187.75   3rd Qu.: 53.00                      3rd Qu.: 82.50  
##  Max.   :250.00   Max.   :999.00                      Max.   :106.00  
##                                                       NA's   :15      
##      Weight          Income         
##  Min.   : 17.70   Length:250        
##  1st Qu.: 54.70   Class :character  
##  Median : 65.35   Mode  :character  
##  Mean   : 66.04                     
##  3rd Qu.: 76.58                     
##  Max.   :103.20                     
##  NA's   :20
summary(df_clean)
##        ID              Age           Gender            Heart_Rate    
##  Min.   :  1.00   Min.   :14.00   Length:250         Min.   : 50.00  
##  1st Qu.: 63.25   1st Qu.:38.00   Class :character   1st Qu.: 68.50  
##  Median :125.50   Median :46.00   Mode  :character   Median : 76.00  
##  Mean   :125.50   Mean   :45.53                      Mean   : 75.86  
##  3rd Qu.:187.75   3rd Qu.:53.00                      3rd Qu.: 82.50  
##  Max.   :250.00   Max.   :77.00                      Max.   :106.00  
##                   NA's   :5                          NA's   :15      
##      Weight          Income         
##  Min.   : 34.80   Length:250        
##  1st Qu.: 54.85   Class :character  
##  Median : 65.60   Mode  :character  
##  Mean   : 66.59                     
##  3rd Qu.: 76.60                     
##  Max.   :103.20                     
##  NA's   :23
glimpse(df_raw)
## Rows: 250
## Columns: 6
## $ ID         <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, …
## $ Age        <int> 51, 32, 47, 44, 37, 15, 36, 33, 46, 39, 40, 999, 42, 42, 14…
## $ Gender     <chr> "nam", "nu", "1", "0", "nam", "Female", "F", "0", "M", "nu"…
## $ Heart_Rate <int> 73, 80, 61, 71, 83, 76, 78, 62, 80, 70, 58, 81, 75, 68, 78,…
## $ Weight     <dbl> 103.2, NA, 74.3, NA, 75.8, NA, NA, NA, 57.3, NA, NA, NA, NA…
## $ Income     <chr> "High", "Medium", "High", NA, "High", "Medium", "Medium", "…
glimpse(df_clean)
## Rows: 250
## Columns: 6
## $ ID         <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, …
## $ Age        <int> 51, 32, 47, 44, 37, 15, 36, 33, 46, 39, 40, NA, 42, 42, 14,…
## $ Gender     <chr> "Male", "Female", "Male", "Female", "Male", "Female", "Fema…
## $ Heart_Rate <int> 73, 80, 61, 71, 83, 76, 78, 62, 80, 70, 58, 81, 75, 68, 78,…
## $ Weight     <dbl> 103.2, NA, 74.3, NA, 75.8, NA, NA, NA, 57.3, NA, NA, NA, NA…
## $ Income     <chr> "High", "Medium", "High", NA, "High", "Medium", "Medium", "…
table(df_clean$Gender, useNA = "ifany")
## 
## Female   Male 
##    134    116
  • Sau khi làm sạch dữ liệu, em nhận thấy bộ dữ liệu đã trở nên nhất quán và dễ sử dụng.

    • Ở biến Age, các giá trị bất thường sinh học đã được xử lý thành NA, nhờ đó tránh làm sai lệch các thống kê mô tả và phân tích sau này.

    • Ở biến Gender, các cách nhập liệu không đồng nhất như nam, nu, M, F, 1, 0, Female đã được chuẩn hóa về hai nhóm thống nhất là “Male” và “Female”.

  • Kết quả summary(df_clean)glimpse(df_clean) cho em thấy cấu trúc dữ liệu sau làm sạch rõ ràng hơn cho việc phân tích.

  • Qua bước này, em thấy rằng mã hóa dữ liệu có vai trò rất quan trọng. Nếu dữ liệu ban đầu không được chuẩn hóa, thì cùng một nhóm đối tượng có thể bị chia thành nhiều nhóm khác nhau. Khả năng làm sai kết quả thống kê và khiến việc phân tích trở nên thiếu tin cậy.

Bài 3

Khoảng trống tử thần (Missing Data)

[CẢM NGHĨ VÀ TƯ DUY CỦA BẠN]

Câu hỏi: Dựa vào lý thuyết Buổi 2, hãy áp định nghĩa và phân loại chính xác 3 cơ chế cho 3 cột biến số trên. Giải thích lí do.

Trả lời:

  • Heart_Rate: MCAR (Missing Completely At Random)
    Giá trị thiếu xảy ra hoàn toàn ngẫu nhiên, không liên quan đến đặc điểm của người tham gia hay giá trị nhịp tim của họ. Vì máy đo trục trặc ngẫu nhiên hoặc người nhập liệu bỏ sót ngẫu nhiên một số trường hợp.

  • Weight: MAR (Missing At Random)
    Em cho rằng biến cân nặng phù hợp với MAR hơn, khả năng thiếu dữ liệu có thể phụ thuộc vào các biến đã quan sát được như tuổi hoặc giới tính. Ví dụ, một số nhóm người tham gia có thể không được cân hoặc bị bỏ sót nhiều hơn các nhóm khác.

  • Income: MNAR (Missing Not At Random)
    Khả năng thuộc cơ chế MNAR, vì việc không trả lời thu nhập thường liên quan trực tiếp đến chính giá trị thu nhập của người tham gia. Ví dụ, người có thu nhập quá thấp hoặc quá cao có thể ngại khai báo.