Berlawanan dari% dalam%


262

Variabel kategorikal V1 dalam bingkai data D1 dapat memiliki nilai yang diwakili oleh huruf-huruf dari A hingga Z. Saya ingin membuat subset D2, yang mengecualikan beberapa nilai, katakanlah, B, N dan T. Pada dasarnya, saya ingin perintah yang lawan dari %in%

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

66
tidak masuk%? ( !(x %in% y)). Kadang hidup bisa mudah ...
Joris Meys

Jawaban:


355

Anda dapat menggunakan !operator pada dasarnya membuat TRUE FALSE dan setiap FALSE TRUE. begitu:

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

EDIT: Anda juga dapat membuat operator sendiri:

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

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

5
Penggunaan opsi kedua diilustrasikan di halaman bantuan (cocok) (di mana Anda akan mendapatkan jika Anda mengetik ?"%in%") di mana operator baru dipanggil %w/o%.
IRTFM

23
juga, lihat ?Negatemisalnya"%ni%" <- Negate("%in%")
baptiste

2
Negate bekerja untuk saya ketika digunakan setelah mendefinisikan operator baru, seperti yang disarankan oleh baptiste, misalnya subset(df, variable %ni% c("A", "B")), tetapi tidak ketika digunakan secara langsung, misalnyasubset(df, variable Negate("%in%") c("A", "B"))
PatrickT

2
@ Patrick, itu karena hanya operator yang dapat digunakan sebagai operator. dan operator adalah built-in atau mulai dan diakhiri dengan %. Untuk membuat operator, Anda harus menetapkan fungsi dengan dua operan ke nama yang dimulai dan diakhiri dengan %.
domba terbang


31

Jika Anda melihat kode %in%

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

maka Anda harus dapat menulis versi sebaliknya. saya menggunakan

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

Cara lain adalah:

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

solusi yang sangat baik .. Ini bekerja ketika negasi reguler gagal.
agatha

17

Berikut ini adalah versi yang menggunakan filterdi dplyryang menerapkan teknik yang sama dengan jawaban yang diterima dengan meniadakan logika dengan!:

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

12

Menggunakan negatedari purrrjuga melakukan trik dengan cepat dan rapi:

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

Maka penggunaannya, misalnya,

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

2
Ada juga built-in Negateyang melakukan hal yang sama. Satu-satunya perbedaan adalah bahwa panggilan purr as_mapperpada hal yang Anda lewati, saat Negatepanggilan match.fun. rdocumentation.org/packages/purrr/versions/0.2.5/topics/… stat.ethz.ch/R-manual/R-devel/library/base/html/match.fun.html
domba terbang

7

purrr::compose() adalah cara cepat lain untuk mendefinisikan ini untuk digunakan nanti, seperti pada:

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

3

Solusi lain bisa menggunakan setdiff

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

D2 = setdiff(D1, D0)

D2 adalah bagian yang Anda inginkan.



0

Saya pikir penggunaan yang paling jelas adalah adil

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

Bagaimana ini berbeda secara substansial dari jawaban yang sudah diposting di sini?
camille

0
library(roperators)

1 %ni% 2:10

Meskipun ini mungkin jawaban yang benar, itu akan lebih bermanfaat dengan penjelasan tambahan tentang mengapa itu bekerja. Pertimbangkan untuk mengeditnya untuk memasukkan perincian lebih lanjut, dan jika Anda merasa itu lebih baik daripada jawaban yang diterima yang diposting hampir satu dekade yang lalu.
Jeremy Caney


-1

Bantuan untuk% dalam%,, help("%in%")termasuk, di bagian Contoh, definisi tidak dalam,

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

Mari kita coba:

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

kalau tidak

"%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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.