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.