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.