Chuyển đến nội dung chính

Cách dùng na.rm để xử lý giá trị thiếu trong R

Chúng ta đặt na.rm = TRUE trong các hàm R thường dùng để loại trừ giá trị thiếu (NA). Việc này giúp tính toán thống kê chính xác và tăng độ tin cậy cho kết quả.
· 8 phút đọc

Khám phá cùng AI

Dữ liệu đang được tạo ra và tiêu thụ với tốc độ công nghiệp để thúc đẩy các quyết định kinh doanh quan trọng. Tuy nhiên, một thách thức phổ biến trong phân tích dữ liệu là sự xuất hiện của các giá trị thiếu. Điều này có thể làm sai lệch kết quả, khiến bất kỳ nhà phân tích dữ liệu nào cũng buộc phải xử lý chúng hiệu quả. Trong R, một trong những công cụ cơ bản để quản lý giá trị thiếu là tham số na.rm.

Bài viết này giải thích tầm quan trọng của việc xử lý dữ liệu thiếu, cách na.rm trong R hoạt động, minh họa việc sử dụng trong nhiều hàm khác nhau và kết thúc bằng việc thảo luận một số kỹ thuật thay thế để nhận diện và xử lý dữ liệu thiếu.

Câu trả lời ngắn gọn: na.rm là gì?

Tham số na.rm trong R là viết tắt của "loại bỏ NA" và bỏ qua các giá trị NA (thiếu) trong quá trình tính toán. Bằng cách đặt na.rm = TRUE, các hàm như mean(), sum(), min(), max(), median() và sd() sẽ tính kết quả mà không bị ảnh hưởng bởi giá trị thiếu.

Tham số na.rm, được viết thường, nhận giá trị Boolean—TRUE hoặc FALSE. Khi đặt na.rm = TRUE, R sẽ loại trừ các giá trị NA khỏi phép tính. Nếu không có tham số này, các hàm sẽ trả về NA nếu dữ liệu có chứa giá trị thiếu. Xem ví dụ.

vector_with_na <- c(1, 2, NA)

sum(vector_with_na, na.rm = TRUE) # removes NA values — returns 3
sum(vector_with_na) # includes NA values — returns NA
sum(vector_with_na, na.rm = FALSE) # includes NA values — returns NA

Xem khóa học Introduction to R để tìm hiểu thêm về lập trình R cơ bản.

Vì sao nên dùng na.rm?

Xử lý giá trị thiếu rất quan trọng trong phân tích dữ liệu để đảm bảo kết quả chính xác, vì chúng có thể ảnh hưởng đáng kể đến các phép tính thống kê, vô tình dẫn đến kết luận sai. Sử dụng na.rm giúp thuận tiện tránh lỗi bằng cách bỏ qua các giá trị thiếu, từ đó thực hiện tính toán đáng tin cậy và duy trì tính toàn vẹn dữ liệu.

Khóa học Data Cleaning in R sẽ hữu ích để nâng cao kỹ năng phân tích dữ liệu của chúng ta.

Các hàm thường dùng với na.rm: Một vài ví dụ thực tiễn

Giờ hãy tìm hiểu cách dùng na.rm trong R. Nhiều hàm R tích hợp tham số na.rm (mặc định là FALSE). Dưới đây là một số ví dụ phổ biến:

sum()

Đúng như tên gọi, sum() tính tổng các giá trị trong một vector. Hãy tạo một vector tên vector_with_na, mà chúng ta sẽ dùng xuyên suốt hướng dẫn này.

vector_with_na <- c(1, 2, NA, 4)

sum(vector_with_na) 
# Returns NA

sum(vector_with_na, na.rm = TRUE) 
# Returns 7

mean()

Với cùng ví dụ, hàm mean() tính trung bình, tức giá trị trung bình của các phần tử trong vector.

mean(vector_with_na) 
# Returns NA

mean(vector_with_na, na.rm = TRUE) 
# Returns 2.33

sd()

Tiếp tục với vector_with_na, sd() tính độ lệch chuẩn của vector.

sd(vector_with_na) 
# Returns NA

sd(vector_with_na, na.rm = TRUE) 
# Returns 1.53

min()

min() tìm giá trị nhỏ nhất.

min(vector_with_na) 
# Returns NA

min(vector_with_na, na.rm = TRUE) 
# Returns 1

max()

max() tìm giá trị lớn nhất.

max(vector_with_na) 
# Returns NA

max(vector_with_na, na.rm = TRUE) 
# Returns 4

median()

median() tìm giá trị ở giữa khi sắp xếp theo thứ tự.

median(vector_with_na) 
# Returns NA

median(vector_with_na, na.rm = TRUE) 
# Returns 2

Lưu ý rằng nếu không có na.rm = TRUE thì tất cả các hàm tổng hợp này sẽ trả về NA.

Bằng cách đặt na.rm = TRUE, các hàm này loại trừ giá trị NA, giúp tính toán chính xác và có ý nghĩa. Lộ trình kỹ năng R Programming Fundamentals có thể là nguồn tài liệu tốt để hiểu rõ hơn cách dùng và cú pháp của các hàm này.

Xử lý giá trị thiếu trong các cấu trúc dữ liệu khác nhau

Hãy xem cách xử lý giá trị thiếu trong các cấu trúc dữ liệu khác nhau. Trước khi tiếp tục, hãy xem hướng dẫn Làm chủ cấu trúc dữ liệu trong ngôn ngữ lập trình R nếu bạn muốn tìm hiểu thêm về cấu trúc dữ liệu trong R. 

Vector

Trong vector, na.rm có thể được dùng trực tiếp trong các hàm để loại trừ giá trị thiếu. Các ví dụ ở phần trước đều là minh họa cho na.rm khi áp dụng trên vector.

Data frame

Với data frame, có thể áp dụng na.rm trong các hàm dùng cho cột cụ thể hoặc trên các hàng bằng apply() như dưới đây:

apply(X, MARGIN, FUN)

Trong đó:

  • X: một mảng, data frame, hoặc ma trận

  • MARGIN: đối số xác định nơi áp dụng hàm:

    • MARGIN=1 để thao tác theo hàng

    • MARGIN=2 để thao tác theo cột

    • MARGIN=c(1,2) để thao tác cả hàng và cột

  • FUN: chỉ định hàm sẽ áp dụng. Có thể dùng các hàm dựng sẵn như mean(), median(), sum(), min(), max(), và các hàm tự định nghĩa.

Hãy tạo một data frame để tham chiếu trong suốt hướng dẫn này.

dataframe_with_na <- data.frame(col1 = c(1, NA, 3, 6), col2 = c(4, 5, NA, 7))

print(dataframe_with_na)
# Returns
#   col1 col2
# 1    1    4
# 2   NA    5
# 3    3   NA
# 4    6    7

apply(dataframe_with_na, 1, mean)
# Returns
# [1] 2.5  NA  NA 6.5

apply(dataframe_with_na, 1, mean, na.rm = TRUE)
# Returns
# [1] 2.5 5.0 3.0 6.5

apply(dataframe_with_na, 2, mean)
# Returns
# col1 col2 
#  NA   NA 

apply(dataframe_with_na, 2, mean, na.rm = TRUE)
# Returns   
#   col1     col2 
# 3.333333 5.333333

List

Hàm lapply() trong R dùng để áp dụng một hàm xác định cho từng phần tử của list, vector hoặc data frame, và trả về một list có cùng độ dài. Hàm này không cần tham số MARGIN, vì nó tự động áp dụng phép toán cho tất cả phần tử.

Cú pháp:

lapply(vector_with_na, fun)

Trong đó:

  • vector_with_na: List, vector hoặc data frame đầu vào.
  • fun: Hàm sẽ được áp dụng cho từng phần tử dữ liệu đầu vào.

Hãy hiểu lapply() qua ví dụ về list. Ở đây chúng ta có một list các nhóm (item_1 và item_2) với các phần tử tương tự data frame (dataframe_with_na). Mục tiêu là tìm trung bình của mỗi nhóm.

list_with_na <- list(item_1=c(1, NA, 3, 6), item_2=c(4, 5, NA, 7))

lapply(list_with_na, mean)
# Returns
# $item_1
# [1] NA
# 
# $item_2
# [1] NA

lapply(list_with_na, mean, na.rm =TRUE)
# Returns
# $item_1
# [1] 3.333333
# 
# $item_2
# [1] 5.333333

Hàm sapply() tương tự lapply() nhưng trả về một mảng hoặc ma trận thay vì list. Hãy dùng list (list_with_na) và sapply() để tính trung bình các giá trị của mỗi nhóm bên trong.

sapply(list_with_na, mean)
# Returns
# a  b 
# NA NA 

sapply(list_with_na, mean, na.rm = TRUE)

# Returns
# a        b 
# 3.333333 5.333333

Giờ, hãy dùng data frame (dataframe_with_na) và sapply() để tính tổng các giá trị của từng cột.

sapply(dataframe_with_na, sum)

# Returns
# col1 col2 
# NA   NA 

sapply(dataframe_with_na, sum, na.rm=TRUE)
# Returns
# col1 col2 
# 10   16

Để hiểu rộng hơn về thao tác dữ liệu trong R, khóa học Data Manipulation with dplyr rất được khuyến nghị. Nếu bạn còn chưa vững nhóm hàm apply(), hãy đọc Hướng dẫn về họ hàm Apply trong R của chúng tôi.

So sánh với na.omit() và complete.cases()

na.omit(): Hàm này loại bỏ toàn bộ các hàng chứa giá trị NA trong data frame. Hãy hiểu bằng ví dụ:

na.omit(dataframe_with_na)
# Returns
# col1 col2
# 1    1    4
# 4    6    7

complete.cases(): Ngược lại, complete.cases() xác định các hàng không có bất kỳ giá trị NA nào và trả về một giá trị boolean tương ứng với mỗi hàng (FALSE cho hàng có NA và ngược lại). Có thể dùng để lọc các giá trị không thiếu trong data frame như dưới đây.

complete.cases(dataframe_with_na)
# Returns
# [1]  TRUE FALSE FALSE  TRUE

dataframe_with_na[complete.cases(dataframe_with_na), ]
# Returns
# col1 col2
# 1    1    4
# 4    6    7

Kỹ thuật nâng cao để xử lý giá trị thiếu

Ngoài na.rm, R còn cung cấp các phương pháp nâng cao để xử lý dữ liệu thiếu:

Dùng is.na() để nhận diện giá trị thiếu

is.na() có thể áp dụng trực tiếp lên vector hoặc data frame để nhận diện dữ liệu thiếu. Hàm trả về TRUE tương ứng với mỗi giá trị thiếu.

is.na(vector_with_na)
# Returns
# [1] FALSE FALSE  TRUE FALSE

is.na(dataframe_with_na)
# Returns
# col1  col2
# [1,] FALSE FALSE
# [2,]  TRUE FALSE
# [3,] FALSE  TRUE
# [4,] FALSE FALSE

Áp dụng các phương pháp thế giá trị (imputation)

Imputation thay thế các giá trị thiếu bằng giá trị ước tính, như trung bình hoặc trung vị, như dưới đây:

vector_with_na[is.na(vector_with_na)] <- mean(vector_with_na, na.rm = TRUE)

print(vector_with_na)
# Returns
# [1] 1.000000 2.000000 2.333333 4.000000

dataframe_with_na[is.na(dataframe_with_na)] <- sapply(dataframe_with_na, mean, na.rm=TRUE)
print(dataframe_with_na)
# Returns
# col1     col2
# 1 1.000000 4.000000
# 2 3.333333 5.000000
# 3 3.000000 5.333333
# 4 6.000000 7.000000

Dùng hàm summary()

Thú vị là hàm summary() khác với việc dùng na.rm để xử lý giá trị thiếu. Mặc định, summary() tự động loại trừ các giá trị thiếu khi tính thống kê tóm tắt và đồng thời báo cáo số lượng NA có trong dữ liệu.

Hãy chạy summary() trên vector vector_with_na:

summary(vector_with_na)
#Returns
#   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
#  1.000   1.500   2.000   2.333   3.000   4.000       1

Và trên data frame dataframe_with_na:

summary(dataframe_with_na)
# Returns
# col1           col2     
# Min.   :1.00   Min.   :4.00  
# 1st Qu.:2.50   1st Qu.:4.75  
# Median :3.00   Median :5.00  
# Mean   :3.25   Mean   :5.25  
# 3rd Qu.:3.75   3rd Qu.:5.50  
# Max.   :6.00   Max.   :7.00 

Khóa học Intermediate R cung cấp kiến thức chuyên sâu cho những ai quan tâm đến các kỹ thuật xử lý dữ liệu nâng cao.

Thực hành tốt nhất khi xử lý giá trị thiếu

Xử lý giá trị thiếu hiệu quả bao gồm một số thực hành tốt nhất:

Luôn kiểm tra giá trị thiếu

Xác định và hiểu mức độ dữ liệu thiếu trước khi thực hiện tính toán. Ví dụ dưới đây cho thấy data frame có tổng cộng 2 giá trị thiếu.

print(dataframe_with_na)
# Returns
# col1 col2
# 1    1    4
# 2   NA    5
# 3    3   NA
# 4    6    7

sum(is.na(dataframe_with_na))
# Returns
# [1] 2

Dùng kiểm tra điều kiện

Luôn xác minh sự hiện diện của dữ liệu thiếu và áp dụng các kỹ thuật thế giá trị phù hợp, đảm bảo xử lý tốt mọi trường hợp biên.

if(any(is.na(dataframe_with_na))) {  
  if (class(dataframe_with_na) == "data.frame") {    
   dataframe_with_na[is.na(dataframe_with_na)] <- sapply(dataframe_with_na, median, na.rm=TRUE)      
  }
}

print(dataframe_with_na)
# Returns
# col1 col2
# 1    1    4
# 2    3    5
# 3    3    5
# 4    6    7

Cân nhắc ngữ cảnh

Hiểu vì sao dữ liệu bị thiếu và chọn phương pháp xử lý phù hợp — loại bỏ hay thế giá trị.

Để có cách tiếp cận có hệ thống trong phân tích dữ liệu và xử lý giá trị thiếu, khóa học Data Cleaning in R có thể là nguồn tài liệu tuyệt vời.

Kết luận

Hiểu và sử dụng na.rm là chìa khóa để đảm bảo phân tích dữ liệu đáng tin cậy và chính xác. Hãy thực hành dùng na.rm trong các dự án R và khám phá các kỹ thuật nâng cao để xử lý toàn diện dữ liệu thiếu.

Để học thêm, hãy khám phá các tài nguyên sau:

Vidhi Chugh

Tác giả

Vidhi Chugh

Tôi là một Chiến lược gia và Nhà đạo đức học về AI, làm việc tại giao điểm giữa khoa học dữ liệu, sản phẩm và kỹ thuật để xây dựng các hệ thống máy học có khả năng mở rộng. Được xếp hạng trong danh sách “Top 200 Nhà đổi mới trong Kinh doanh và Công nghệ” trên thế giới, tôi theo đuổi sứ mệnh dân chủ hóa máy học và giản lược thuật ngữ chuyên môn để mọi người đều có thể tham gia vào quá trình chuyển đổi này.

Câu hỏi thường gặp

na.rm trong R là gì?

Tham số na.rm trong R là viết tắt của "loại bỏ NA". Khi đặt TRUE, nó yêu cầu các hàm bỏ qua giá trị NA (thiếu) trong quá trình tính toán, đảm bảo kết quả chính xác.

Cách dùng na.rm trong các hàm R thường gặp như thế nào?

Bạn có thể dùng na.rm trong các hàm như sum(), mean(), sd(), min(), max() và median() bằng cách đặt na.rm = TRUE để loại trừ giá trị thiếu khỏi phép tính.

Vì sao việc xử lý giá trị thiếu lại quan trọng trong phân tích dữ liệu?

Giá trị thiếu có thể làm sai lệch kết quả và dẫn đến kết luận không chính xác. Xử lý chúng hiệu quả sẽ đảm bảo tính toán đáng tin cậy và duy trì tính toàn vẹn dữ liệu.

Có thể dùng na.rm với data frame và list trong R không?

Có, na.rm có thể dùng với data frame thông qua các hàm như apply(), và với list bằng lapply() và sapply(), để loại trừ giá trị thiếu khi thao tác trên các cấu trúc dữ liệu này.

Một số kỹ thuật nâng cao để xử lý giá trị thiếu trong R là gì?

Ngoài na.rm, các kỹ thuật nâng cao gồm có dùng is.na() để nhận diện giá trị thiếu, áp dụng các phương pháp thế giá trị để thay thế chúng, và tận dụng các hàm như na.omit() và complete.cases() cho các tác vụ làm sạch dữ liệu phức tạp hơn.

Chủ đề

Liên quan