Nhiệm vụ:
pacman,
rio, tidyverse.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: - Đ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
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"
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) và
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.
[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.