Tập hợp con các hàng chứa giá trị NA (bị thiếu) trong cột đã chọn của khung dữ liệu


96

Chúng tôi có khung dữ liệu từ tệp CSV. Khung dữ liệu DFcó các cột chứa các giá trị quan sát và một cột ( VaR2) chứa ngày thực hiện phép đo. Nếu ngày không được ghi lại, thì tệp CSV chứa giá trị NAcho dữ liệu bị thiếu.

Var1  Var2 
10   2010/01/01
20   NA
30   2010/03/01

Chúng tôi muốn sử dụng lệnh tập hợp con để xác định một khung dữ liệu mới new_DFsao cho nó chỉ chứa các hàng có NA'giá trị từ cột ( VaR2). Trong ví dụ đã cho, chỉ Hàng 2 mới được chứa trong hàng mới DF.

Lệnh

new_DF<-subset(DF,DF$Var2=="NA") 

không hoạt động, khung dữ liệu kết quả không có mục nhập hàng.

Nếu trong file CSV gốc giá trị NAđược trao đổi với NULL, lệnh cùng tạo ra kết quả mong muốn: new_DF<-subset(DF,DF$Var2=="NULL").

Làm cách nào để phương pháp này hoạt động, nếu đối với chuỗi ký tự, giá trị NAđược cung cấp trong tệp CSV gốc?

Câu trả lời:


145

Không bao giờ sử dụng == 'NA' để kiểm tra các giá trị bị thiếu. Sử dụng is.na()thay thế. Điều này nên làm điều đó:

new_DF <- DF[rowSums(is.na(DF)) > 0,]

hoặc trong trường hợp bạn muốn kiểm tra một cột cụ thể, bạn cũng có thể sử dụng

new_DF <- DF[is.na(DF$Var),]

Trong trường hợp bạn có các giá trị ký tự NA, trước tiên hãy chạy

Df[Df=='NA'] <- NA

để thay thế chúng bằng các giá trị bị thiếu.


2
Cảm ơn câu trả lời nhanh của bạn (điều này rất nhanh)! Thật vậy, do việc phân phối dữ liệu bằng csv, 'NA' là các giá trị ký tự và câu lệnh thứ hai của bạn có thể rất hữu ích. Bạn cũng có thể làm rõ tuyên bố đầu tiên của bạn? Tôi không rõ việc sử dụng rowSums () vì tôi sẽ chỉ kiểm tra một cột cụ thể (có rất nhiều cột). Nếu cột cụ thể đó (trong ví dụ là cột Var2) có chuỗi ký tự 'NA' (tôi sẽ thay thế nó bằng câu lệnh thứ hai của bạn), thì tôi muốn chọn toàn bộ hàng để trở thành một phần của khung dữ liệu mới .
John

@John: đã cập nhật. Điểm đó là sử dụng is.na, tôi đã hiểu sai khi bạn muốn kiểm tra tất cả các biến.
Joris Meys

3
nên có new_DF <- DF[is.na(DF$Var),], tức là dường như có thêm một dấu (ngoặc sau DF[?
PatrickT

39

NA là một giá trị đặc biệt trong R, không trộn giá trị NA với chuỗi "NA". Tùy thuộc vào cách dữ liệu được nhập, các ô "NA" và "NULL" của bạn có thể thuộc nhiều loại khác nhau (hành vi mặc định là chuyển đổi chuỗi "NA" thành giá trị NA và đặt nguyên là chuỗi "NULL").

Nếu sử dụng read.table () hoặc read.csv (), bạn nên xem xét đối số "na.strings" để thực hiện việc nhập dữ liệu sạch và luôn hoạt động với các giá trị R NA thực.

Một ví dụ, hoạt động trong cả hai trường hợp ô "NULL" và "NA":

DF <- read.csv("file.csv", na.strings=c("NA", "NULL"))
new_DF <- subset(DF, is.na(DF$Var2))

1
Cảm ơn câu trả lời của bạn. Nếu tôi hiểu đúng thì câu lệnh đầu tiên sẽ tương tự như Df [Df == 'NA'] <- NA trong ví dụ về Joris? Sự khác biệt (nhỏ) sau đó sẽ là nó được thực hiện ngay trong trạng thái của bạn ngay từ đầu, khi khung dữ liệu được tạo (đây là một phương pháp lập trình rất sạch và do đó tôi thích nó).
John

Chính xác. Joris đề xuất thay thế chuỗi "NA" bằng giá trị NA theo cách thủ công, ở đây tôi chỉ đề xuất sử dụng tính năng "na.strings" của read.table () để đạt được mục đích tương tự.
maressyl

Câu trả lời của Joris thực sự là cách "ưa thích" để đạt được thành tích này (nếu bạn đang viết điều này trong một kịch bản). Xem: stackoverflow.com/questions/9860090/…
Jonathan

@Jonathan: Hai ý tưởng khác biệt ở đây, chủ đề bạn trích dẫn nói rằng "[" nên được ưu tiên trên "tập hợp con", nhưng chúng ta đang nói về đối số "na.strings" trong read.table (), tập hợp con của tôi ở đây chỉ để hình dung cac hiệu ưng.
maressyl

32

complete.casesđưa ra TRUEkhi tất cả các giá trị trong một hàng khôngNA

DF[!complete.cases(DF), ]

11
new_data <- data %>% filter_all(any_vars(is.na(.))) 

Điều này sẽ tạo một khung dữ liệu mới ( new_data) chỉ với các giá trị bị thiếu trong đó.

Hoạt động tốt nhất để theo dõi các giá trị mà sau này bạn có thể giảm vì chúng có một số cột bị thiếu quan sát (NA).


3

Hãy thử thay đổi điều này:

new_DF<-dplyr::filter(DF,is.na(Var2)) 

Bạn có thể giải thích tại sao điều này hoạt động, điều này làm gì, v.v.?
csilk

new_DF <-dplyr :: filter (DF, is.na (Var2)) về cơ bản nó sử dụng chức năng lọc của gói dplyr và lọc ra bất kỳ quan sát nào trong cột Var2 thỏa mãn điều kiện is.na tức là chúng chọn tất cả quan sát với NA
drhnis

1
Thể hiện độc đáo hơn như DF %>% filter(is.na(Var2))sau library(dplyr).
Joe

-1

In tất cả các hàng có dữ liệu NA:

tmp <- data.frame(c(1,2,3),c(4,NA,5));
tmp[round(which(is.na(tmp))/ncol(tmp)),]

@ZheyuanLi Nếu bạn không thích câu trả lời, chỉ cần bỏ phiếu xuống. Chỉnh sửa câu trả lời để đề xuất gắn cờ KHÔNG phải là hành động phù hợp. Để lại bình luận nếu bạn cảm thấy cần thiết.
Manfred Radlwimmer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.