ตรงข้ามกับ% ใน%


262

ตัวแปรเด็ดขาด V1 ในกรอบข้อมูล D1 สามารถมีค่าที่แสดงด้วยตัวอักษรจาก A ถึง Z ฉันต้องการสร้าง D2 ชุดย่อยซึ่งไม่รวมค่าบางค่าเช่น B, N และ T โดยทั่วไปฉันต้องการคำสั่งที่เป็น ตรงกันข้ามกับ %in%

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

66
ไม่ใช่% ใน%? ( !(x %in% y)) บางครั้งชีวิตอาจเป็นเรื่องง่าย ...
Joris Meys

คำตอบ:


355

คุณสามารถใช้!โอเปอเรเตอร์เพื่อสร้าง TRUE FALSE และ FALSE TRUE ดังนั้น:

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

แก้ไข: คุณสามารถสร้างโอเปอเรเตอร์ได้ด้วยตนเอง:

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

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

5
การใช้งานของตัวเลือกที่สองคือตัวอย่างในความช่วยเหลือ (แข่งขัน) หน้า (ที่คุณจะได้รับถ้าคุณพิมพ์?"%in%") %w/o%ในกรณีที่ผู้ประกอบการใหม่ที่เรียกว่า
IRTFM

23
ดูได้?Negateเช่น"%ni%" <- Negate("%in%")
baptiste

2
Negate ใช้งานได้เมื่อฉันใช้หลังจากกำหนดตัวดำเนินการใหม่ตามที่ baptiste แนะนำsubset(df, variable %ni% c("A", "B"))แต่ไม่ใช่เมื่อใช้โดยตรงเช่นsubset(df, variable Negate("%in%") c("A", "B"))
PatrickT

2
@PatrickT นั่นเป็นเพราะตัวดำเนินการเท่านั้นที่สามารถใช้เป็นตัวดำเนินการได้ %และผู้ประกอบการในตัวหรือเริ่มต้นและจบลงด้วยการ %เพื่อสร้างผู้ประกอบการคุณต้องกำหนดฟังก์ชั่นที่มีสองตัวถูกดำเนินการให้เป็นชื่อที่ขึ้นต้นและลงท้ายด้วย
บินแกะ


31

ถ้าคุณดูรหัส %in%

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

จากนั้นคุณควรจะสามารถเขียนเวอร์ชันตรงข้ามของคุณ ฉันใช้

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

อีกวิธีคือ:

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

ทางออกที่ดีเยี่ยม .. มันใช้งานได้เมื่อการปฏิเสธปกติล้มเหลว
agatha

17

นี่คือรุ่นที่ใช้filterในdplyrที่ใช้เทคนิคเดียวกับคำตอบที่ยอมรับโดยการปฏิเสธตรรกะด้วย!:

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

12

การใช้negateจากpurrrเคล็ดลับก็ทำได้อย่างรวดเร็วและเป็นระเบียบ:

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

ตัวอย่างเช่นการใช้งานคือ

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

2
นอกจากนี้ยังมีในตัวNegateที่ทำเช่นเดียวกัน แตกต่างเพียงว่าสาย purrr as_mapperในสิ่งที่คุณผ่านในขณะที่โทรNegate rdocumentation.org/packages/purrr/versions/0.2.5/topics/… stat.ethz.ch/R-manual/R-devel/library/base/html/match.fun.htmlmatch.fun
flying sheep

7

purrr::compose() เป็นอีกวิธีที่รวดเร็วในการกำหนดสิ่งนี้เพื่อใช้ในภายหลังเช่นเดียวกับใน:

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

3

วิธีแก้ปัญหาอื่นอาจใช้ setdiff

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

D2 = setdiff(D1, D0)

D2 เป็นชุดย่อยที่คุณต้องการ



0

ฉันคิดว่าการใช้งานที่ชัดเจนเป็นเพียงแค่

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

สิ่งนี้แตกต่างอย่างมากจากคำตอบที่โพสต์แล้วที่นี่
คามิลล์

0
library(roperators)

1 %ni% 2:10

แม้ว่านี่อาจเป็นคำตอบที่ถูกต้อง แต่ก็มีประโยชน์มากกว่าด้วยคำอธิบายเพิ่มเติมว่าทำไมมันถึงใช้ได้ ลองแก้ไขเพื่อรวมรายละเอียดเพิ่มเติมและถ้าคุณรู้สึกว่ามันดีกว่าคำตอบที่ยอมรับซึ่งโพสต์เมื่อเกือบสิบปีที่แล้ว
Jeremy Caney


-1

ความช่วยเหลือสำหรับ% in%, help("%in%")รวมถึงในส่วนตัวอย่างคำนิยามนี้ไม่รวมอยู่ใน

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

มาลองดูกัน:

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

อีกทางเลือกหนึ่ง

"%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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.