3.1 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.

  • Dùng hàm rio::import() để nạp file dữ liệu vào.

  • Dùng hàm summary() và glimpse() để kiểm tra tổng quan.

# Cài đặt và gọi các gói thư viện:
if (!require("pacman")) install.packages("pacman")
pacman::p_load(rio, tidyverse)

# Nhập dữ liệu từ file:
df_raw <- import("raw_health_survey.csv")

# Kiểm tra cấu trúc và kiểu dữ liệu:
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", "…
# Kiểm tra các thông số thống kê cơ bản:
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

[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:

Sau khi chạy lệnh summary(), e thấy dữ liệu này khá lộn xộn :v

  • Biến Age: e chưa hiểu lắm tại sao lại phải lọc 999 trong khi khoảng từ 1xx-999 thì không?

  • Biến Gender: Người nhập liệu ghi nhiều kiểu quá :c (nam, nu, 1, 0,…)

3.2 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.

# Tạo bảng dữ liệu sạch
df_clean <- df_raw %>%
  mutate(
    # Sửa tuổi: Chuyển các giá trị <= 0 hoặc >= 100 thành NA
    Age = ifelse(Age <= 0 | Age >= 100, NA, Age),
    
    # Chuẩn hóa Gender -> 2 nhóm Male và Female
    Gender = case_when(
      Gender %in% c("nam", "Nam", "M", "Male", "1") ~ "Male",
      Gender %in% c("nu", "Nu", "F", "Female", "0") ~ "Female",
      TRUE ~ NA_character_
    )
  )

# Kiểm tra lại sau khi làm sạch
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.   : 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

[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:

  • Đổ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”.

  • Theo cảm nghĩ cá nhân, e thấy việc mã hóa dữ liệu là 1 bước cần thiết để các bước phân tích hay thao tác (?tương tác) với các biến sau này dễ dàng và logic hơn. Nếu không mã hóa về 1 chuẩn, mình có thể bị sót kết quả (kiểu muốn tính tổng nam nhưng lại chỉ đếm “nam”, “1” mà không đếm “male”,…).

3.3 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ế:

  • MCAR – Missing Completely At Random

  • MAR – Missing At Random

  • MNAR – Missing Not At Random

[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: Phân loại 3 cơ chế thiếu dữ liệu trong bài:

  1. MCAR (Thiếu hoàn toàn ngẫu nhiên): Các lỗi gõ nhầm (VD: Age = 999) => Đây là lỗi ngẫu nhiên của người nhập liệu.

  2. MAR (Thiếu ngẫu nhiên): Biến Weight (VD: Nữ giới thường có xu hướng ngại điền cân nặng hơn nam giới. Sự thiếu hụt này giải thích được bằng biến Gender.)

  3. MNAR (Thiếu không ngẫu nhiên): Biến Income. Những tỷ phú hoặc đk khó khăn thường chủ động fake thu nhập :v (việc thiếu dữ liệu phụ thuộc vào chính giá trị của nó)