Bài 1

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

Nhiệm vụ:

if (!require("pacman")) install.packages("pacman")
pacman::p_load(rio, tidyverse)
df_raw <- rio::import("raw_health_survey.csv")
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:
- Outliers về mặt sinh học rút ra được từ kết quả summary():
+ Age:
Min = 0
Max = 999
+ Weight:
Min = 17.7

- Ở biến Gender, từ kết quả glimpse() ta thấy, người nhập liệu dùng nhiều cách khác nhau để miêu tả cho cùng một giới tính

unique(df_raw$Gender)
## [1] "nam"    "nu"     "1"      "0"      "Female" "F"      "M"      "Male"

=> Gây khó khăn cho phân tích và cần được làm sạch trước khi xử lý.


Bài 2

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

Nhiệm vụ:

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"
# 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:
- So sánh trước với sau làm sạch

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", "…

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Ả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:
Age là MCAR do trong df_raw không có NA, 5 giá trị NA trên 250 mẫu chỉ xuất hiện sau khi loại bỏ tuổi 0 và 999 nên khả năng cao là lỗi nhập liệu hoặc thiếu khi thu thập dữ liệu.

df_raw %>%
  filter(Age %in% c(0, 999))
##    ID Age Gender Heart_Rate Weight Income
## 1  12 999     nu         81     NA   <NA>
## 2  45   0      0         74   51.3   High
## 3  88 999      1         NA   84.4   High
## 4 102   0    nam         76   82.0   High
## 5 201 999   Male         78   50.0 Medium

Heart_Rate là MAR là do có thể lỗi nhập liệu, nhưng có thể dự đoán được dựa trên các biến khác như Age, Weight, Gender…(còn phụ thuộc vào biến khác chứ không phải không phụ thuộc gì cả như MCAR)

Income là MNAR vì thu nhập là biến nhạy cảm. Những người có thu nhập rất thấp hoặc rất cao thường không muốn khai báo, nên là việc NA là do chủ ý chứ không phải ngẫu nhiên.