Missing Values
Khái niệm
Missing values hay còn gọi là những giá trị bị thiếu, không được điền hoặc không được cập nhật vào bộ dữ liệu, đây có thể là kết quả của một quá trình sai sót trong quá trình nhập liệu. Việc làm sạch dữ liệu đầu vào bao giờ cũng đi kèm với công việc xử lý missing values.Missing values
Cách xử lý dữ liệu missing values
Trước tiên cần phải hiểu rõ bản chất của missing values, rồi sau đó sẽ đưa ra giải pháp phù hợp để xử lý missing values.
Thông thường, có 2 cách để xử lý missing values:
Cách 1: Loại bỏ missing values (trong trường hợp missing values đó không quan trọng đối với dữ liệu của chúng ta hoặc số lượng missing values quá ít - chỉ chiếm khoảng dưới 3% tổng số quan sát trong 1 biến nhất định).
Cách 2: Thay thế missing values bằng một giá trị khác. Việc thay thế bằng giá trị nào sẽ phụ thuộc vào việc bản chất của missing values trong những trường hợp đó là gì.
Câu hỏi đặt ra lúc này là: Vậy thì nếu cần phải thay thế missing values bằng một giá trị khác, thì nên thay thế bằng giá trị nào?
Trường hợp biến có missing values là biến số - numeric: Có thể thay thế missing values bằng những giá trị như: 0, median, mean, v.v. tùy vào từng trường hợp nhất định.
Trường hợp biến có missing values là biến categorical: Có thể nhóm những trường hợp missing values vào 1 nhóm, đặt tên là Missing.
Dữ liệu giả định
Giả sử ở đây chúng ta có dữ liệu về thu nhập của 10 nhân viên của một công ty, các nhân viên đến từ các tỉnh khác nhau. Trong dữ liệu do sai sót khi nhập tiền lương, một số nhân viên bị thiếu tiền lương và không có thông tin về tỉnh. Cùng xử lý nội dung này:
<- c("Quang", "Thanh", "Long", "Jacky", "Lindan", "Lee", "Phan", "Tam",
ten "Vu", "Tien")
<- as.numeric(c(sample(12:19, 7, replace = TRUE), NA, NA, NA))
age
<- as.numeric(c(NA, NA, sample(6:15, 6, replace = FALSE), 80, NA))
luong_VND
<- c("Hai Phong","Thai Nguyen", "Bac Ninh", NA ,"Thai Nguyen","Thai Nguyen", "Lang Son", "Tuyen Quang", "Bac Kan", "Long An")
province
<- data.frame(ten, age, luong_VND, province)
mydata
# Tóm tắt dữ liệu
%>% datatable() mydata
%>% str() mydata
## 'data.frame': 10 obs. of 4 variables:
## $ ten : chr "Quang" "Thanh" "Long" "Jacky" ...
## $ age : num 16 19 17 18 12 14 19 NA NA NA
## $ luong_VND: num NA NA 6 11 12 14 15 7 80 NA
## $ province : chr "Hai Phong" "Thai Nguyen" "Bac Ninh" NA ...
%>% summary() mydata
## ten age luong_VND province
## Length:10 Min. :12.00 Min. : 6.00 Length:10
## Class :character 1st Qu.:15.00 1st Qu.: 9.00 Class :character
## Mode :character Median :17.00 Median :12.00 Mode :character
## Mean :16.43 Mean :20.71
## 3rd Qu.:18.50 3rd Qu.:14.50
## Max. :19.00 Max. :80.00
## NA's :3 NA's :3
Biến tuổi(age) và biến thu nhập (luong_VND) đều có các giá trị NA. Mỗi cột đều có 3 giá trị NA, với tỷ lệ là 30%, như vậy tỷ lệ missing values là 30%, do đó chúng ta cần thay thế những giá trị này bằng một giá trị thay thế khác nào đó
Đối với biến age, chúng ta nhận thấy đa số tuổi nhân viên không có sự chênh lệch đáng kể, do đó chúng ta có thể thay thế các giá trị NA trong cột tuổi bằng giá trị trung bình (mean).
# Hàm case_when() trong thư viện dplyr sử dụng như điều kiện if_else. Nếu các dữ liệu là trống, sử dụng condition ~ mean(...), ngược lại trả lại giá trị TRUE cho các quan sát khác.
%>%
mydata mutate(age_new = case_when(is.na(age) ~ ceiling(mean(age, na.rm = TRUE)), TRUE ~ age)) -> mydata
%>%
mydata datatable()
Như vậy, chúng ta đã xử lý xong các missing values cho cột age bằng cách thay các giá trị trung bình. Xem lại giá trị dữ liệu với biến thu nhập
%>%
mydata summary()
## ten age luong_VND province
## Length:10 Min. :12.00 Min. : 6.00 Length:10
## Class :character 1st Qu.:15.00 1st Qu.: 9.00 Class :character
## Mode :character Median :17.00 Median :12.00 Mode :character
## Mean :16.43 Mean :20.71
## 3rd Qu.:18.50 3rd Qu.:14.50
## Max. :19.00 Max. :80.00
## NA's :3 NA's :3
## age_new
## Min. :12.00
## 1st Qu.:16.25
## Median :17.00
## Mean :16.60
## 3rd Qu.:17.75
## Max. :19.00
##
Độ dao động của cột này trong khoảng (0, 80). Đa số lương các nhân viên bằng nhau, tuy nhiên có một nhân viên có giá trị đến 80, tức là rất cao so với các nhân viên còn lại. Đây là một giá trị ngoại lai (outlier) ảnh hưởng rất lớn đến giá trị của biến, do đó để phản ánh đúng giá trị bản chất của dữ liệu, chúng ta sẽ sử dụng đến giá trị trung vị (median).
%>%
mydata mutate(luong_new = case_when(is.na(luong_VND) ~ median(luong_VND, na.rm = TRUE), TRUE ~ luong_VND)) -> mydata
%>%
mydata datatable()
Như vậy, missing values đã được thay thế bằng giá trị trung vị của dữ liệu lương Đối với trường hợp còn lại là tên tỉnh, một nhân viên là Jacky không có kê khai về tên tỉnh. Giá trị này thực tế không có ý nghĩa nhiều, do đó chúng ta có thể loại bỏ giá trị này. Tuy nhiên các thông tin của nhân viên Jacky vẫn quan trọng, do đó chúng ta có thể thêm dữ liệu cho giá trị này là Missing. Biến province là biến phân loại, và do đó sau khi thêm dữ liệu chúng ta cần đưa về nó là giá trị factor trong trường hợp cần kê khai bảng thống kê theo tỉnh nếu có nhiều dữ liệu
library(dplyr)
%>%
mydata mutate(province_new = case_when(is.na(province) ~ "Missing", TRUE ~ province)
%>% as.factor()) -> mydata
mydata
## ten age luong_VND province age_new luong_new province_new
## 1 Quang 16 NA Hai Phong 16 12 Hai Phong
## 2 Thanh 19 NA Thai Nguyen 19 12 Thai Nguyen
## 3 Long 17 6 Bac Ninh 17 6 Bac Ninh
## 4 Jacky 18 11 <NA> 18 11 Missing
## 5 Lindan 12 12 Thai Nguyen 12 12 Thai Nguyen
## 6 Lee 14 14 Thai Nguyen 14 14 Thai Nguyen
## 7 Phan 19 15 Lang Son 19 15 Lang Son
## 8 Tam NA 7 Tuyen Quang 17 7 Tuyen Quang
## 9 Vu NA 80 Bac Kan 17 80 Bac Kan
## 10 Tien NA NA Long An 17 12 Long An
Đại học Công nghệ Thông tin và Truyền thông Thái Nguyên. Vì yêu mà đến. Cùng chia sẻ các kiến thức về phân tích dữ liệu và xây dựng cộng động R ngày càng phát triển.
ICTU - Vì yêu mà đến