10

I have a list:

L <- c("a","b","c","d","e")

I also have a subset of this list:

L1 <- c("b","d","e")

I am trying to create a new list that does not contain the subset list.

I have tried:

L[L!%in%L1]
L[L%in%!L1]
L[L%in%-L1]

but this does not work. I would be grateful for your help.

adam.888
  • 7,686
  • 17
  • 70
  • 105

2 Answers2

16

It should be

L[!(L %in% L1)]

Because of operator precedence (?Syntax), you can also do

L[!L %in% L1]

Finally, you also have:

setdiff(L, L1)
flodel
  • 87,577
  • 21
  • 185
  • 223
  • 2
    But `setdiff` will fail if there are repeated elements in either list. – Carl Witthoft Oct 26 '14 at 12:09
  • "Fail" is a bit of a harsh statement for 1) The OP's example has no duplicates and 2) he is asking for a "subset": where the mathematical definition of a "set" excludes duplicates. Let's just say that if `L` had duplicates, the output would be different. And let the OP decide or clarify. – flodel Oct 26 '14 at 12:17
  • Hmph :-) I'm often accused of being a concrete thinker, engineering-style, and here I tried to point out that in a more general case there'd be a problem... :-( . After all, the very self-named `R` function `subset` doesn't follow algebraic rules! – Carl Witthoft Oct 26 '14 at 12:23
  • 1
    Ok. I think you are right to point the more general case, and that it would give a different output. But I don't think you should call it a problem or a failure. – flodel Oct 26 '14 at 12:29
3

You could also play with vecsets:vsetdiff (disclaimer: I wrote this scary package). Unlike proper set theory as implemented in setdiff, vsetdiff will return all elements of a vector which do not appear in the second argument, thus allowing for multiple instances of a given value.

vsetdiff(L,L1)
[1] "a" "c"
vsetdiff(L1,L)
character(0)
Carl Witthoft
  • 20,573
  • 9
  • 43
  • 73