9

This is really simple but I can't seem to locate it. I know R has a negated version of %in% that returns "not in." Obviously I could just use !(x %in% y) , but the language includes an already negated construct and I want to use it, goshdarnit.

So what's the function? Searches as well as %nin% and %notin% all fail.

Bonus internets to you if you benchmark your answer versus !(x %in% y) using the following sample data:

x <- sample( sample(letters,5), 10^3, replace=TRUE)
y <- sample( letters, 10^5, replace=TRUE)
Ari B. Friedman
  • 71,271
  • 35
  • 175
  • 235
  • 1
    I don't think it does. I just make my own using `Negate`. – joran Jul 03 '12 at 00:33
  • Which begs the question: Is `Negate` any faster/slower than `!`? But seriously, I coulda sworn I've seen it before. – Ari B. Friedman Jul 03 '12 at 00:34
  • I think an add on package has what you're after but it's not too rough on the index finger to type `!`. Especially since your parenthesis are unnecessary. `!x %in% y` works just fine. I'm guessing that Negate will be slower as often higher order functions are. – Tyler Rinker Jul 03 '12 at 00:41
  • 1
    Oh, those pesky packages. And you're right...I've included the parens for (to me, at least) clarity for so long I forgot that order of operations makes them redundant. Please Excuse My Darned Annoying Slipup. – Ari B. Friedman Jul 03 '12 at 00:44
  • @ttmaccer Yeah, and that's why I like my version: `'%ni%' <- Negate('%in%')`. Soooooo simple. – joran Jul 03 '12 at 01:04
  • I've answered this before, in atleast two locations, here's [one](http://stackoverflow.com/questions/7494848/standard-way-to-remove-multiple-elements-from-a-dataframe/7498829#7498829). This is one area where the SO search seems to fail though. I wish we could put all the right search terms in one spot so this could be more easily found. – Chase Jul 03 '12 at 02:27
  • @Chase There it is. Voting to close. I agree about the search terms. I tried.... – Ari B. Friedman Jul 03 '12 at 02:50
  • Would `setdiff` suffice, if `x[!x %in% y]` is the outcome you want. – mnel Jul 03 '12 at 04:26
  • ...with the difference that `setdiff` throws away duplicates, so it is more like `unique(x[!x %in% y])`. – flodel Jul 03 '12 at 10:04

1 Answers1

15

Just out of interest. Defining

"%w/o%" <- function(x, y) x[!x %in% y] 
'%ni%' <- Negate('%in%')

> benchmark(y[y%ni%x], y%w/o%x,replications=1000)
         test replications elapsed relative user.self sys.self user.child
2   y %w/o% x         1000    5.32 1.000000      4.60     0.70         NA
1 y[y %ni% x]         1000    5.34 1.003759      4.68     0.65         NA
  sys.child
2        NA
1        NA

Do i get a cookie?

shhhhimhuntingrabbits
  • 7,397
  • 2
  • 23
  • 23