A categorical variable V1 in a data frame D1 can have values represented by the letters from A to Z. I want to create a subset D2, which excludes some values, say, B, N and T. Basically, I want a command which is the opposite of %in%
D2 = subset(D1, V1 %in% c("B", "N", "T")) 213 Answers
You can use the ! operator to basically make any TRUE FALSE and every FALSE TRUE. so:
D2 = subset(D1, !(V1 %in% c('B','N','T'))) EDIT: You can also make an operator yourself:
'%!in%' <- function(x,y)!('%in%'(x,y)) c(1,3,11)%!in%1:10 [1] FALSE FALSE TRUE 7How about:
`%ni%` <- Negate(`%in%`) c(1,3,11) %ni% 1:10 # [1] FALSE FALSE TRUE 4Here is a version using filter in dplyr that applies the same technique as the accepted answer by negating the logical with !:
D2 <- D1 %>% dplyr::filter(!V1 %in% c('B','N','T')) 0If you look at the code of %in%
function (x, table) match(x, table, nomatch = 0L) > 0L then you should be able to write your version of opposite. I use
`%not in%` <- function (x, table) is.na(match(x, table, nomatch=NA_integer_)) Another way is:
function (x, table) match(x, table, nomatch = 0L) == 0L 0Using negate from purrr also does the trick quickly and neatly:
`%not_in%` <- purrr::negate(`%in%`) Then usage is, for example,
c("cat", "dog") %not_in% c("dog", "mouse") 1purrr::compose() is another quick way to define this for later use, as in:
`%!in%` <- compose(`!`, `%in%`) Another solution could be using setdiff
D1 = c("A",..., "Z") ; D0 = c("B","N","T") D2 = setdiff(D1, D0) D2 is your desired subset.
Hmisc has %nin% function, which should do this.
library(roperators) 1 %ni% 2:10 If you frequently need to use custom infix operators, it is easier to just have them in a package rather than declaring the same exact functions over and over in each script or project.
1The package collapse has it built in: %!in%.
The help for %in%, help("%in%"), includes, in the Examples section, this definition of not in,
"%w/o%" <- function(x, y) x[!x %in% y] #-- x without y
Lets try it:
c(2,3,4) %w/o% c(2,8,9) [1] 3 4 Alternatively
"%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 require(TSDT) c(1,3,11) %nin% 1:10 # [1] FALSE FALSE TRUE For more information, you can refer to:
In Frank Harrell's package of R utility functions, he has a %nin% (not in) which does exactly what the original question asked. No need for wheel reinvention.