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")
## Loading required package: 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â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 vô lí:

    • Biến Age: Max = 999, Min = 0

    • Biến Weight: Min = 17.7

  • Ở biến Gender, người nhập liệu đã không thống nhất cách ghi (nam/nu, Male/Female, M/F, 0/1).

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)
# Dùng ngữ pháp dplyr để dọn dẹp
df_clean <- df_raw %>%
  mutate(
    # 1. Đổi các lỗi tuổi vô lý (> 100) thành NA
    Age = ifelse(Age > 100, NA, Age),
    # 2. Đưa Gender về chuẩn "Male" và "Female"
    Gender = case_when(
      Gender %in% c("nam", "M", "Male", "1") ~ "Male",
      Gender %in% c("nu", "F", "Female", "0") ~ "Female",
      TRUE ~ NA_character_ # Các trường hợp không khớp sẽ thành NA
    )
  )
# Kiểm tra lại kết quả sau khi làm sạch
view(df_clean)

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:

  • Trước:
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", "…
  • Sau:
summary(df_clean)
##        ID              Age           Gender            Heart_Rate    
##  Min.   :  1.00   Min.   : 0.00   Length:250         Min.   : 50.00  
##  1st Qu.: 63.25   1st Qu.:37.00   Class :character   1st Qu.: 68.50  
##  Median :125.50   Median :45.00   Mode  :character   Median : 76.00  
##  Mean   :125.50   Mean   :45.16                      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   :3                          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_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", "…
  • Nhận xét:

    • Sau khi làm sạch, biến Age đã hợp lí hơn và biến Gender đã được thống nhất cách ghi.

    • Mã hoá giúp cho số liệu thô được thống nhất về một ngôn ngữ chung mà máy có thể nhận diện được. Giúp loại bỏ các giá trị bất thường gây sai lệch chỉ số trung bình và đồng nhất các ký hiệu thành các nhóm đối tượng thống nhất. Qua đó, dữ liệu trở nên sạch sẽ, tin cậy hơn khi thực hiện các phép kiểm định thống kê.

BÀI 3: KHOẢNG TRỐNG TỬ THẦN (MISSING DATA)

Trong bộ dữ liệu của bạn, có rất nhiều ô trống (NA). Trong dịch tễ học, chúng được chia làm 3 cơ chế:

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:

  • MCAR (Missing Completely At Random): Heart_Rate: Do lỗi kỹ thuật ngẫu nhiên của thiết bị đo hoặc mất tín hiệu lúc lấy mẫu, không liên quan đến đặc điểm sinh học của bệnh nhân.

  • MAR (Missing At Random): Weight: Một số nhóm đối tượng cụ thể như người già hoặc phụ nữ có tâm lý ngại cân, việc mất dữ liệu này phụ thuộc vào biến số khác là Age hoặc Gender.

  • MNAR (Missing Not At Random): Income: Những người có thu nhập quá cao hoặc quá thấp chủ động từ chối khai báo, việc mất dữ liệu phụ thuộc trực tiếp vào chính giá trị của biến số đó.