Đối diện% trong%


262

Một biến phân loại V1 trong khung dữ liệu D1 có thể có các giá trị được biểu thị bằng các chữ cái từ A đến Z. Tôi muốn tạo một tập hợp con D2, loại trừ một số giá trị, giả sử, B, N và T. Về cơ bản, tôi muốn có một lệnh sự đối lập của %in%

D2 = subset(D1, V1 %in% c('B','N',T'))

66
không% trong%? ( !(x %in% y)). Cuộc sống đôi khi có thể dễ dàng ...
Joris Meys

Câu trả lời:


355

!Về cơ bản, bạn có thể sử dụng toán tử để thực hiện bất kỳ TRUE FALSE và mọi FALSE TRUE. vì thế:

D2 = subset(D1, !(V1 %in% c('B','N','T')))

EDIT: Bạn cũng có thể tự thực hiện một toán tử:

'%!in%' <- function(x,y)!('%in%'(x,y))

c(1,3,11)%!in%1:10
[1] FALSE FALSE  TRUE

5
Việc sử dụng tùy chọn thứ hai được minh họa trong trang trợ giúp (khớp) (nơi bạn sẽ nhận được nếu bạn nhập ?"%in%") nơi toán tử mới được gọi %w/o%.
IRTFM

23
đồng thời, xem ?Negateví dụ"%ni%" <- Negate("%in%")
baptiste

2
Phủ nhận làm việc cho tôi khi được sử dụng sau khi xác định các nhà điều hành mới, theo đề nghị của Baptiste, ví dụ như subset(df, variable %ni% c("A", "B")), nhưng không phải khi sử dụng trực tiếp, ví dụ nhưsubset(df, variable Negate("%in%") c("A", "B"))
PatrickT

2
@PatrickT đó là vì chỉ các toán tử mới có thể được sử dụng làm toán tử. và các toán tử được tích hợp sẵn hoặc bắt đầu và kết thúc bằng %. Để tạo một toán tử, bạn cần gán một hàm có hai toán hạng cho một tên bắt đầu và kết thúc bằng %.
cừu bay


31

Nếu bạn nhìn vào mã của %in%

 function (x, table) match(x, table, nomatch = 0L) > 0L

sau đó bạn sẽ có thể viết phiên bản ngược lại của bạn. tôi sử dụng

`%not in%` <- function (x, table) is.na(match(x, table, nomatch=NA_integer_))

Một cách khác là:

function (x, table) match(x, table, nomatch = 0L) == 0L

giải pháp tuyệt vời..Nó hoạt động khi phủ định thường xuyên thất bại.
agatha

17

Đây là một phiên bản sử dụng filtertrong dplyrđó áp dụng kỹ thuật tương tự như câu trả lời được chấp nhận bằng cách phủ định logic với !:

D2 <- D1 %>% dplyr::filter(!V1 %in% c('B','N','T'))

12

Sử dụng negatetừ purrrcũng làm thủ thuật nhanh chóng và gọn gàng:

`%not_in%` <- purrr::negate(`%in%`)

Sau đó, việc sử dụng là, ví dụ,

c("cat", "dog") %not_in% c("dog", "mouse")

2
Cũng có một tích hợp sẵn Negatemà làm như vậy. Sự khác biệt duy nhất là purrr gọi as_mappervào điều bạn vượt qua, trong khi Negategọi match.fun. rdocumentation.org/packages/purrr/versions/0.2.5/topics/ trên stat.ethz.ch/R-manual/R-devel/l Library / base / html / match.fun.html
cừu bay

7

purrr::compose() là một cách nhanh chóng khác để xác định điều này để sử dụng sau, như trong:

`%!in%` <- compose(`!`, `%in%`)

3

Một giải pháp khác có thể được sử dụng setdiff

D1 = c("A",..., "Z") ; D0 = c("B","N","T")

D2 = setdiff(D1, D0)

D2 là tập hợp con mong muốn của bạn.



0

Tôi nghĩ rằng việc sử dụng rõ ràng nhất chỉ là

!('Spain' %in% c('Germany', 'France', 'Italy'))

Làm thế nào để điều này khác biệt đáng kể với câu trả lời đã được đăng ở đây?
camille

0
library(roperators)

1 %ni% 2:10

Mặc dù đây có thể là một câu trả lời đúng, nhưng nó sẽ hữu ích hơn với lời giải thích bổ sung về lý do tại sao nó hoạt động. Cân nhắc chỉnh sửa nó để bao gồm thêm thông tin chi tiết và nếu bạn cảm thấy nó tốt hơn câu trả lời được chấp nhận đã được đăng gần một thập kỷ trước.
Jeremy Caney


-1

Trợ giúp cho% in%, help("%in%")bao gồm, trong phần Ví dụ, định nghĩa này không có trong,

"%w/o%" <- function(x, y) x[!x %in% y] #-- x without y

Hãy thử nó:

c(2,3,4) %w/o% c(2,8,9)
[1] 3 4

Hoặc

"%w/o%" <- function(x, y) !x %in% y #--  x without y
c(2,3,4) %w/o% c(2,8,9)
# [1] FALSE  TRUE  TRUE
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.