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'))

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

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


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

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'))

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")

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%`)

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.



0

Ich denke, die klarste Verwendung ist gerecht

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

Wie unterscheidet sich dies wesentlich von den hier bereits veröffentlichten Antworten?
Camille

0
library(roperators)

1 %ni% 2:10

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.