Lập trình với R: Dữ liệu bị thiếu

Missing data

Missing data


Dữ liệu bị thiếu (missing values) đóng một vai trò quan trọng trong thống kê và phân tích dữ liệu. Thông thường, missing values không nên bị bỏ qua mà cần được nghiên cứu cẩn thận để xem xét xem điều gì khiến cho các missing values này bị thiếu. Trong R, NA được sử dụng để thể hiện các giá trị không tồn tại (not available) hay bị thiếu (missing) theo nghĩa thống kê. Trong bài viết này, ta sẽ tìm hiểu kỹ hơn về các giá trị này.

Bất kỳ các phép toán nào liên quan đến NA đều cho ra kết quả là NA. Để minh hoạ điều này, ta hãy tạo vector x sau:

x <- c(44, NA, 5, NA)

Bây giờ, thử nhân x với 3 ta sẽ có kết quả sau

x * 3
[1] 132  NA  15  NA

Qua ví dụ trên, ta thấy kết quả nhân tương ứng với các giá trị NA đều trả về kết quả là NA. Để thêm phần thú vị, ta sẽ tạo một vector gồm 1000 phần tử được sinh bởi phân phối chuẩn (standard normal distribution) như sau:

y <- rnorm(1000)

Tiếp theo, ta tạo một vector chứa 1000 giá trị NA và gán vào biến z:

z <- rep(NA, 1000)

Cuối cùng, ta sẽ chọn ra 100 phần tử từ 2000 phần tử (kết hợp y và z) sao cho ta không biết được phân bố và số lượng của giá trị NA. Bằng cách chọn một cách ngẫu nhiên từ hàm sample():

my_data <- sample(c(y, z), 100)
[1]  0.550893857           NA           NA           NA           NA
[6] -0.002621131 -0.907090922  0.788269976           NA           NA
[11]           NA           NA -0.038122731 -2.605959866           NA
[16] -0.470568690  2.152948945  0.202475339  0.893350730 -1.004269945
[21]           NA -0.530532387 -0.475984348           NA -0.115786112
[26]           NA -0.793165436           NA           NA -0.291748252
[31]           NA           NA           NA           NA  0.941268965
[36]           NA  1.517767208           NA           NA           NA
[41]  0.701788959  0.412406263  0.689065960 -1.343563844           NA
[46]           NA -0.554544540 -0.550998991 -0.562853738           NA
[51]           NA  0.578162066 -0.453684157           NA  1.024030606
[56] -0.701279562 -1.623681883  1.133164454  0.905578224           NA
[61]  1.806205570           NA           NA -0.631171487  0.300602298
[66]  0.719448972 -0.974375427           NA -0.247937644 -0.210655115
[71]           NA           NA           NA -0.046714208           NA
[76] -0.865193192           NA           NA           NA  0.221010081
[81]           NA           NA           NA           NA -0.512130003
[86]           NA           NA -0.838666534           NA           NA
[91]           NA -0.120863009           NA           NA -0.492633785
[96]           NA -0.575522749           NA           NA           NA

Đầu tiên, chúng ta sẽ kiểm tra xem vị trí của các giá trị NA được phân bố như thế nào trong dữ liệu chúng ta vừa mới tạo. Sử dụng hàm is.na() cho phép chúng ta biết giá trị phần tử hiện tại có mang giá trị NA hay không.

my_na <- is.na(my_data)
my_na
[1] FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE
[13] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE
[25] FALSE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE
[37] FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE
[49] FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE
[61] FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE
[73]  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE
[85] FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE
[97] FALSE  TRUE  TRUE  TRUE

Những vị trí có giá trị là TRUE cho chúng ta biết phần tử mang giá trị NA tương ứng trong biến my_data. Ngược lại, những phần tử mang gái trị là FALSE tương ứng với các giá trị chọn được từ phân phối chuẩn y. Chúng ta sẽ không sử dụng toán tử `==` để kiểm tra từng phần tử trong my_data có mang giá trị NA hay không. Vì làm như vậy, chúng ta sẽ nhận được kết quả trả về là NA chứ không phải TRUE/FALSE như ở trên. Lý do, NA thật ra không phải là một gía trị cụ thể mà chỉ là cách thể hiện đây là chỗ mà đáng lẽ ra phải có giá trị. Do đó, toán tử logic không thể áp dụng được trong trường hợp này và R không có lựa chọn nào khác là trả về toàn bộ kết quả đều là NA có số lượng bằng với số lượng phần tử của my_data.

my_data == NA
[1] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[26] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[51] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[76] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA

Trở lại bài toán của chúng ta. Hiện tại, chúng ta có vector my_na, có giá trị TRUE cho những phần tử NA và FALSE cho những phần tử mang giá trị numeric, chúng ta sẽ tính số lượng xuất hiện các giá trị NA này trong my_data. Kỹ thuật được sử dụng ở đây đó là bên trong R giá trị TRUE thật chất được xem như giá trị 1 và FALSE có giá trị 0. Vì vậy, nếu chúng ta tính tổng trên TRUE và FALSE, chúng ta sẽ có được tổng của các giá trị TRUE.

# số lượng các phần tử mang giá trị NA
sum(my_na)
[1] 53

Bây giờ, chúng ta đã hiểu được NA là gì. Tiếp theo ta hãy xem kiểu dữ liệu kế tiếp biểu diễn cho dữ liệu bị thiếu đó là NaN (not a number). Để trả về NaN, ta có thể thử chia 0 bởi 0 hay vô cùng (Inf) trừ cho vô cùng.

0/0
[1] NaN
Inf - Inf
[1] NaN

Qua các ví dụ trên ta phần nào hiểu được khái niệm dữ liệu bị thiếu cũng như biết cách vận dụng để rút ra được tập dữ liệu toàn vẹn không chứa các giá trị NA hay NaN này.

Nguồn tham khảo: http://swirlstats.com/

Advertisements

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Đăng xuất / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Đăng xuất / Thay đổi )

Connecting to %s