Di fronte a% in%


262

Una variabile categorica V1 in un frame di dati D1 può avere valori rappresentati dalle lettere dalla A alla Z. Voglio creare un sottoinsieme D2, che esclude alcuni valori, ad esempio B, N e T. In sostanza, voglio un comando che sia il contrario di %in%

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

66
Non in%? ( !(x %in% y)). La vita può essere facile a volte ...
Joris Meys,

Risposte:


355

È possibile utilizzare l' !operatore per fare praticamente qualsiasi VERO FALSO e ogni FALSO VERO. così:

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

EDIT: Puoi anche creare un operatore tu stesso:

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

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

5
L'uso della seconda opzione è illustrato nella pagina di aiuto (corrispondenza) (dove si arriva se si digita ?"%in%") dove viene chiamato il nuovo operatore %w/o%.
IRTFM,

23
inoltre, vedi ?Negatead es."%ni%" <- Negate("%in%")
battista

2
Negate ha funzionato per me quando utilizzato dopo aver definito il nuovo operatore, come suggerito da Baptist, ad esempio subset(df, variable %ni% c("A", "B")), ma non quando utilizzato direttamente, ad esempiosubset(df, variable Negate("%in%") c("A", "B"))
PatrickT

2
@PatrickT è perché solo gli operatori possono essere usati come operatori. e gli operatori sono integrati o iniziano e finiscono con %. Per creare un operatore, è necessario assegnare una funzione con due operandi a un nome che inizia e termina con %.
pecora volante


31

Se guardi il codice di %in%

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

allora dovresti essere in grado di scrivere la tua versione di contrario. Io uso

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

Un altro modo è:

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

soluzione eccellente ... Ha funzionato quando la negazione regolare ha fallito.
agatha,

17

Ecco una versione che usa filterin dplyrche applica la stessa tecnica della risposta accettata negando la logica con!:

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


7

purrr::compose() è un altro modo rapido per definirlo per un uso successivo, come in:

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

3

Un'altra soluzione potrebbe essere l'utilizzo setdiff

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

D2 = setdiff(D1, D0)

D2 è il sottoinsieme desiderato.



0

Penso che l'uso più chiaro sia giusto

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

In che modo differisce sostanzialmente dalle risposte già pubblicate qui?
Camille,

0
library(roperators)

1 %ni% 2:10

Sebbene questa possa essere una risposta corretta, sarebbe più utile con una spiegazione aggiuntiva del perché funzioni. Valuta di modificarlo per includere ulteriori dettagli e se ritieni che sia migliore della risposta accettata che è stata pubblicata quasi un decennio fa.
Jeremy Caney,


-1

La guida per% in%, help("%in%")include, nella sezione Esempi, questa definizione di non in,

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

Proviamolo:

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

In alternativa

"%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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.