2015-10-02 24 views
10

Khi tôi sử dụng filter từ gói dplyr để giảm mức biến số, filter cũng giảm giá trị NA. Dưới đây là ví dụ:Tại sao bộ lọc của dplyr giảm giá trị NA từ một biến yếu tố?

library(dplyr) 
set.seed(919) 
(dat <- data.frame(var1 = factor(sample(c(1:3, NA), size = 10, replace = T)))) 
# var1 
# 1 <NA> 
# 2  3 
# 3  3 
# 4  1 
# 5  1 
# 6 <NA> 
# 7  2 
# 8  2 
# 9 <NA> 
# 10 1 

filter(dat, var1 != 1) 
# var1 
# 1 3 
# 2 3 
# 3 2 
# 4 2 

Điều này có vẻ không lý tưởng - Tôi chỉ muốn thả các hàng ở nơi var1 == 1.

Có vẻ như điều này xảy ra vì bất kỳ comparison with NA returns NA, trong đó filter sau đó giảm xuống. Vì vậy, ví dụ: filter(dat, !(var1 %in% 1)) sẽ tạo ra kết quả chính xác. Nhưng có cách nào để yêu cầu filter không bỏ các giá trị NA không?

+2

@akrun Vì lý do nào đó tôi không nhận được thông báo này: P. Vâng tôi nghĩ rằng OP đã biết về điều này, như ông đã đề cập 'lọc (dat,! (Var1% trong% 1))' đó là tương tự, nhưng tôi nghĩ rằng đây sẽ là cách duy nhất để làm điều đó với 'dplyr :: bộ lọc'. – LyzandeR

+1

Tôi không nghĩ rằng có một cách rõ ràng để nói 'bộ lọc' không giảm' NA' giá trị nhưng nói chung, các truy vấn NA hợp lý có thể được xử lý bằng cách sử dụng toán tử '% in%' cơ sở và phủ định, được định nghĩa là ' % ni% <- Phủ nhận ('% in%') '. Vì vậy, bạn có thể sử dụng 'bộ lọc (dat, var1% ni% 1)' mà sẽ làm việc. Xem http://stackoverflow.com/a/11303276/4269699 và http://stackoverflow.com/a/27015823/4269699 – wjchulme

+1

Có, tôi đã biết về cả phương pháp này và cách tiếp cận mà @LyzandeR sử dụng cho câu trả lời . Dường như bộ lọc không có tùy chọn rõ ràng cho "giữ NA", vì vậy các cách giải quyết này sẽ ổn. Cảm ơn bạn đã giúp đỡ. –

Trả lời

14

Bạn có thể sử dụng này:

filter(dat, var1 != 1 | is.na(var1)) 
    var1 
1 <NA> 
2 3 
3 3 
4 <NA> 
5 2 
6 2 
7 <NA> 

Và nó sẽ không.

Cũng chỉ để hoàn thành, giảm NAS là hành vi dự kiến ​​của filter như bạn có thể nhìn thấy từ sau:

test_that("filter discards NA", { 
    temp <- data.frame(
    i = 1:5, 
    x = c(NA, 1L, 1L, 0L, 0L) 
) 
    res <- filter(temp, x == 1) 
    expect_equal(nrow(res), 2L) 
}) 

thử nghiệm này trên được lấy từ các bài kiểm tra cho filter từ github.

+2

Tham gia một chút vào lãnh thổ dựa trên ý kiến, bạn có một ý tưởng tại sao đây là phương pháp được lựa chọn không? Hành vi này là bất ngờ đối với tôi (hôm nay tôi bị nó cắn). – Heisenberg

+1

@Heisenberg Tôi giả định theo Hadley, hầu hết mọi người đều không muốn nhận bất kỳ NA nào khi lọc. Nhưng đó là câu hỏi dành cho nhà phát triển/người bảo trì, tức là Hadley. – LyzandeR

Các vấn đề liên quan