if (!require("pacman")) install.packages("pacman")
## Loading required package: 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", "…
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).
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)
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
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", "…
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ê.
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
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ố đó.