Oposto de% em%


262

Uma variável categórica V1 em um quadro de dados D1 pode ter valores representados pelas letras de A a Z. Quero criar um subconjunto D2, que exclui alguns valores, digamos, B, N e T. Basicamente, quero um comando que seja o oposto de %in%

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

66
não em%? ( !(x %in% y)) A vida pode ser fácil, às vezes ...
Joris Meys

Respostas:


355

Você pode usar o !operador para fazer basicamente qualquer VERDADEIRO FALSO e todo FALSO VERDADEIRO. tão:

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

EDIT: Você também pode criar um operador:

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

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

5
O uso da segunda opção é ilustrado na página de ajuda (correspondência) (onde você chegaria se digitasse ?"%in%") onde o novo operador é chamado %w/o%.
IRTFM 29/04

23
veja também, ?Negatepor exemplo,"%ni%" <- Negate("%in%")
baptiste

2
Negar trabalhou para mim quando usado após definição do novo operador, como sugerido por baptiste, por exemplo subset(df, variable %ni% c("A", "B")), mas não quando usado diretamente, por exemplosubset(df, variable Negate("%in%") c("A", "B"))
PatrickT

2
@PatrickT, porque apenas operadores podem ser usados ​​como operadores. e os operadores estão integrados ou iniciam e terminam %. Para criar um operador, você precisa atribuir uma função com dois operandos a um nome começando e terminando com %.
ovelha voadora


31

Se você olhar para o código de %in%

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

então você poderá escrever sua versão do oposto. eu uso

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

Outra maneira é:

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

excelente solução .. Funcionou quando a negação regular falhou.
Agatha

17

Aqui está uma versão usando filterem dplyrque se aplica a mesma técnica que a resposta aceita, negando a lógica com!

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


7

purrr::compose() é outra maneira rápida de definir isso para uso posterior, como em:

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

3

Outra solução poderia estar usando setdiff

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

D2 = setdiff(D1, D0)

D2 é o subconjunto desejado.



0

Eu acho que o uso mais claro é apenas

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

Como isso difere substancialmente das respostas já postadas aqui?
camille

0
library(roperators)

1 %ni% 2:10

Embora essa possa ser uma resposta correta, seria mais útil com explicações adicionais sobre por que funciona. Considere editá-lo para incluir mais detalhes e, se achar que é melhor do que a resposta aceita, publicada quase uma década atrás.
Jeremy Caney


-1

A ajuda para% em% help("%in%")inclui, na seção Exemplos, esta definição de não em,

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

Vamos tentar:

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

alternativamente

"%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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.