Gegenteil von% in%

262

Eine kategoriale Variable V1 in einem Datenrahmen D1 kann Werte haben, die durch die Buchstaben von A bis Z dargestellt werden. Ich möchte eine Teilmenge D2 erstellen, die einige Werte ausschließt, z. B. B, N und T. Grundsätzlich möchte ich einen Befehl, der ist das Gegenteil von %in%

D2 = subset(D1, V1 %in% c('B','N',T'))
user702432
quelle
66
nicht in%? ( !(x %in% y)). Das Leben kann manchmal einfach sein ...
Joris Meys

Antworten:

355

Sie können den !Operator verwenden, um grundsätzlich jede TRUE FALSE und jede FALSE TRUE zu machen. so:

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

BEARBEITEN: Sie können einen Operator auch selbst erstellen:

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

c(1,3,11)%!in%1:10
[1] FALSE FALSE  TRUE
Sacha Epskamp
quelle
5
Die Verwendung der zweiten Option wird auf der Hilfeseite (Übereinstimmung) veranschaulicht (zu der Sie gelangen würden, wenn Sie tippen würden ?"%in%"), auf der der neue Operator aufgerufen wird %w/o%.
IRTFM
23
siehe auch ?NegatezB"%ni%" <- Negate("%in%")
baptiste
2
Negate funktionierte für mich, wenn es nach der Definition des neuen Operators verwendet wurde, wie von baptiste vorgeschlagen, z. B. subset(df, variable %ni% c("A", "B"))aber nicht, wenn es direkt verwendet wurde, z. B.subset(df, variable Negate("%in%") c("A", "B"))
PatrickT
2
@PatrickT Das liegt daran, dass nur Operatoren als Operatoren verwendet werden können. und Operatoren sind entweder integriert oder beginnen und enden mit %. Um einen Operator zu erstellen, müssen Sie einem Namen, der mit beginnt und endet, eine Funktion mit zwei Operanden zuweisen %.
fliegende Schafe
64

Wie wäre es mit:

'%ni%' <- Negate('%in%')
c(1,3,11) %ni% 1:10
# [1] FALSE FALSE  TRUE
Spencer Castro
quelle
7
Ich gab diese Antwort hier
katastrophales Versagen
31

Wenn Sie sich den Code von ansehen %in%

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

dann sollten Sie in der Lage sein, Ihre Version des Gegenteils zu schreiben. ich benutze

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

Ein anderer Weg ist:

function (x, table) match(x, table, nomatch = 0L) == 0L
Marek
quelle
ausgezeichnete Lösung. Es hat funktioniert, als die reguläre Negation fehlschlug.
Agatha
17

Hier ist eine Version, filterin dplyrder dieselbe Technik wie die akzeptierte Antwort angewendet wird, indem die Logik mit! Negiert wird:

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

Die Verwendung von negatefrom purrrmacht den Trick auch schnell und ordentlich:

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

Dann ist die Verwendung zum Beispiel

c("cat", "dog") %not_in% c("dog", "mouse")
EllaK
quelle
2
Es gibt auch einen eingebauten Negate, der das gleiche tut. Der einzige Unterschied besteht darin, dass purrr das Objekt anruft, as_mapperdas Sie übergeben, während Sie Negatetelefonieren match.fun. rdocumentation.org/packages/purrr/versions/0.2.5/topics/… stat.ethz.ch/R-manual/R-devel/library/base/html/match.fun.html
fliegende Schafe
7

purrr::compose() ist eine weitere schnelle Möglichkeit, dies für die spätere Verwendung zu definieren, wie in:

`%!in%` <- compose(`!`, `%in%`)
edavidaja
quelle
3

Eine andere Lösung könnte verwenden setdiff

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

D2 = setdiff(D1, D0)

D2 ist Ihre gewünschte Teilmenge.

user3373954
quelle
0

Ich denke, die klarste Verwendung ist gerecht

!('Spain' %in% c('Germany', 'France', 'Italy'))
luissevillano
quelle
Wie unterscheidet sich dies wesentlich von den hier bereits veröffentlichten Antworten?
Camille
0
library(roperators)

1 %ni% 2:10
Benbob
quelle
Dies ist zwar eine korrekte Antwort, aber mit einer zusätzlichen Erklärung, warum es funktioniert, nützlicher . Bearbeiten Sie es, um weitere Details aufzunehmen, und wenn Sie der Meinung sind, dass es besser ist als die akzeptierte Antwort, die vor fast einem Jahrzehnt veröffentlicht wurde.
Jeremy Caney
-1

Die Hilfe für% in% help("%in%")enthält im Abschnitt Beispiele diese Definition von nicht in,

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

Lass es uns versuchen:

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

Alternative

"%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
quelle