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'))
pengguna702432
sumber
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
Sacha Epskamp
sumber
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
64

Bagaimana tentang:

'%ni%' <- Negate('%in%')
c(1,3,11) %ni% 1:10
# [1] FALSE FALSE  TRUE
Spencer Castro
sumber
7
Saya memberikan jawaban ini di sini
malapetaka-kegagalan
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
Marek
sumber
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'))
pengguna29609
sumber
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")
EllaK
sumber
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%`)
edavidaja
sumber
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.

pengguna3373954
sumber
0

Saya pikir penggunaan yang paling jelas adalah adil

!('Spain' %in% c('Germany', 'France', 'Italy'))
luissevillano
sumber
Bagaimana ini berbeda secara substansial dari jawaban yang sudah diposting di sini?
camille
0
library(roperators)

1 %ni% 2:10
Benbob
sumber
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
Tony Ladson
sumber