Xử lý dữ liệu missing nâng cao

Tác giả: Nguyễn Hải Trường | 2019-06-30

Trong quá trình phân tích dữ liệu thực tế, chúng ta sẽ thường gặp phải vấn đề missing values. Trong những bài viết trước, RAnalytics đã chia sẻ một số tips xử lý missing values, các bạn có thể tham khảo tại:

http://ranalytics.vn/blog/2019/01/15/2019-01-15-xu-ly-du-lieu-missing/

http://ranalytics.vn/blog/2019/06/20/2019-06-20-loai-bo-hang-va-cot-chua-gia-tri-missing/


Tuy nhiên, câu hỏi đặt ra lúc này là giả sử dữ liệu của chúng ta có rất nhiều biến có missing values, vậy thì làm thế nào để thay thế missing values ở hàng loạt các biến cùng một lúc?

Trong bài viết này, Rnalytics sẽ chia sẻ với các bạn cách giải quyết vấn đề nói trên.

Lấy mẫu 10 quan sát đầu tiên của dữ liệu iris có sẵn trong R để thực hành.

library(dplyr)
set.seed(1) 
data <- iris %>% sample_n(10)
data
##    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
## 1           5.1         3.4          1.5         0.2     setosa
## 2           5.7         2.8          4.5         1.3 versicolor
## 3           5.4         3.0          4.5         1.5 versicolor
## 4           6.3         2.8          5.1         1.5  virginica
## 5           4.7         3.2          1.6         0.2     setosa
## 6           7.4         2.8          6.1         1.9  virginica
## 7           6.3         3.4          5.6         2.4  virginica
## 8           5.6         2.7          4.2         1.3 versicolor
## 9           5.5         2.5          4.0         1.3 versicolor
## 10          4.4         2.9          1.4         0.2     setosa

Thêm một biến mới class vào tập dữ liệu.

data <- data %>% 
  mutate(class = case_when(
    Species == "setosa" ~ "1",
    Species == "versicolor" ~ "2",
    TRUE ~ "3"
  ) %>% as.factor)

data
##    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species class
## 1           5.1         3.4          1.5         0.2     setosa     1
## 2           5.7         2.8          4.5         1.3 versicolor     2
## 3           5.4         3.0          4.5         1.5 versicolor     2
## 4           6.3         2.8          5.1         1.5  virginica     3
## 5           4.7         3.2          1.6         0.2     setosa     1
## 6           7.4         2.8          6.1         1.9  virginica     3
## 7           6.3         3.4          5.6         2.4  virginica     3
## 8           5.6         2.7          4.2         1.3 versicolor     2
## 9           5.5         2.5          4.0         1.3 versicolor     2
## 10          4.4         2.9          1.4         0.2     setosa     1

Giả sử, chúng ta sửa dòng thứ 1 và dòng thứ 3 của tập dữ liệu thành các giá trị NA, để sau đó chúng ta xử lý.

data[c(1,3),] <- NA
data
##    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species class
## 1            NA          NA           NA          NA       <NA>  <NA>
## 2           5.7         2.8          4.5         1.3 versicolor     2
## 3            NA          NA           NA          NA       <NA>  <NA>
## 4           6.3         2.8          5.1         1.5  virginica     3
## 5           4.7         3.2          1.6         0.2     setosa     1
## 6           7.4         2.8          6.1         1.9  virginica     3
## 7           6.3         3.4          5.6         2.4  virginica     3
## 8           5.6         2.7          4.2         1.3 versicolor     2
## 9           5.5         2.5          4.0         1.3 versicolor     2
## 10          4.4         2.9          1.4         0.2     setosa     1
# Định dạng các biến trong tập dữ liệu
data %>% str
## 'data.frame':    10 obs. of  6 variables:
##  $ Sepal.Length: num  NA 5.7 NA 6.3 4.7 7.4 6.3 5.6 5.5 4.4
##  $ Sepal.Width : num  NA 2.8 NA 2.8 3.2 2.8 3.4 2.7 2.5 2.9
##  $ Petal.Length: num  NA 4.5 NA 5.1 1.6 6.1 5.6 4.2 4 1.4
##  $ Petal.Width : num  NA 1.3 NA 1.5 0.2 1.9 2.4 1.3 1.3 0.2
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: NA 2 NA 3 1 3 3 2 2 1
##  $ class       : Factor w/ 3 levels "1","2","3": NA 2 NA 3 1 3 3 2 2 1

Như vậy, dữ liệu mới của chúng ta bây giờ tại tất cả các biến đều có missing values. Bốn biến đầu tiên là biến liên tục (numeric), hai biến cuối cùng là biến rời rạc (factor).

Giả sử, đối với những biến liên tục (numeric) trong dữ liệu, chúng ta sẽ thay thế missing values bằng giá trị 0 bằng câu lệnh sau:

data2 <- data %>% 
  mutate_if(is.numeric,  # Áp dụng với các biến là numeric
            # Những giá trị NA thay bằng 0
            funs(case_when(
              is.na(.) ~ 0,
              TRUE ~ .
            ))
            ) 

data2
##    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species class
## 1           0.0         0.0          0.0         0.0       <NA>  <NA>
## 2           5.7         2.8          4.5         1.3 versicolor     2
## 3           0.0         0.0          0.0         0.0       <NA>  <NA>
## 4           6.3         2.8          5.1         1.5  virginica     3
## 5           4.7         3.2          1.6         0.2     setosa     1
## 6           7.4         2.8          6.1         1.9  virginica     3
## 7           6.3         3.4          5.6         2.4  virginica     3
## 8           5.6         2.7          4.2         1.3 versicolor     2
## 9           5.5         2.5          4.0         1.3 versicolor     2
## 10          4.4         2.9          1.4         0.2     setosa     1

Hoặc nếu muốn thay thế missing values bằng giá trị median, có thể dùng câu lệnh sau:

data %>% 
  mutate_if(is.numeric,  # Áp dụng với các biến là numeric
            # Những giá trị NA thay bằng median
            funs(case_when(
              is.na(.) ~ median(., na.rm = T),
              TRUE ~ .
            ))
  ) 
##    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species class
## 1          5.65         2.8         4.35         1.3       <NA>  <NA>
## 2          5.70         2.8         4.50         1.3 versicolor     2
## 3          5.65         2.8         4.35         1.3       <NA>  <NA>
## 4          6.30         2.8         5.10         1.5  virginica     3
## 5          4.70         3.2         1.60         0.2     setosa     1
## 6          7.40         2.8         6.10         1.9  virginica     3
## 7          6.30         3.4         5.60         2.4  virginica     3
## 8          5.60         2.7         4.20         1.3 versicolor     2
## 9          5.50         2.5         4.00         1.3 versicolor     2
## 10         4.40         2.9         1.40         0.2     setosa     1

Tương tự, đối với những biến rời rạc (factor) trong dữ liệu, chúng ta sẽ thay thế missing values bằng giá trị Missing, sử dụng câu lệnh sau:

data2 %>% 
  # Những biến factor cần convert về dạng character trước
  mutate_if(is.factor, as.character) %>% 
  mutate_if(is.character,
            funs(case_when(
              is.na(.) ~ "Missing",
              TRUE ~ .
            ))         
         )
##    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species   class
## 1           0.0         0.0          0.0         0.0    Missing Missing
## 2           5.7         2.8          4.5         1.3 versicolor       2
## 3           0.0         0.0          0.0         0.0    Missing Missing
## 4           6.3         2.8          5.1         1.5  virginica       3
## 5           4.7         3.2          1.6         0.2     setosa       1
## 6           7.4         2.8          6.1         1.9  virginica       3
## 7           6.3         3.4          5.6         2.4  virginica       3
## 8           5.6         2.7          4.2         1.3 versicolor       2
## 9           5.5         2.5          4.0         1.3 versicolor       2
## 10          4.4         2.9          1.4         0.2     setosa       1

Như vậy, chúng ta đã vừa được học cách thay thế missing values bằng 1 giá trị nhất định ở hàng loạt các biến cùng một lúc bằng việc kết hợp câu lệnh mutate_if()case_when(). Chúc các bạn học tập và làm việc hiệu quả với Ranalytics.vn!

comments powered by Disqus