The %in% operator checks whether the element is present. And NOT IN (%!in%) operator does the exact opposite.
The %!in% is a custom operator that checks if the elements of one vector are not present in another vector. It returns a logical vector of the same length as the left-hand vector, with TRUE for those that don’t match and FALSE for the matches. It is a logical negation of the “in” operator.
Since R does not have a built-in %!in% operator, we must create it. To create a custom infix operator, you must define a function surrounded by a percentage sign, as shown in the above statement.
For a function, we can use the built-in Negate() function to wrap the %in% operator.
Syntax
`%!in%` <- Negate(`%in%`)
# OR
`%!in%` <- function(x, y) !(x %in% y)
Arguments
Name | Value |
x | It is a vector whose elements are checked for absence in “y”. |
y | It is a reference vector for which elements of x are compared. |
Basic usage of %!in% operator
If you use the %!in% operator directly, you will face this error:
could not find function "%!in%" in r
To fix this issue, let’s define the custom %!in% operator.
`%!in%` <- Negate(`%in%`)
Now, you can use the %!in% operator.
v1 <- 4
v2 <- 11
t <- 1:10
`%!in%` <- Negate(`%in%`)
print(v1 %!in% t)
print(v2 %!in% t)
# [1] FALSE
# [1] TRUE
In this code, when the left side of the %in% or %!in% operator contains a single value, the result is a single logical value (TRUE or FALSE).
When the left side is a vector with multiple values, the operator returns a logical vector of the same length.
For %!in%, the result is TRUE for values not found in the right-hand vector and FALSE for those found.
# Define %!in%
`%!in%` <- Negate(`%in%`)
x <- c(11, 21, 19, 48)
y <- c(19, 50, 21)
x %!in% y
# Output: TRUE FALSE FALSE TRUE
Since vector x contains 4 elements, we got the four values in the output because the left side is x and the right side is y of %!in% operator.
Usage with Data Frame
If you have a large data frame and want to exclude some rows, you can use the %!in% operator. So, we can use it as a filter for a data frame.
# Define %!in%
`%!in%` <- Negate(`%in%`)
df <- data.frame(
id = c(11, 19, 21, 48),
name = c("Eleven", "KB", "Krunal", "AJ")
)
# Filter rows where 'id' is NOT 20 or 30
subset(df, id %!in% c(11, 48))
Usage with a list
When you are using a list, you can check a vector that is not in that list and a list that is not in that list.
"%!in%" <- Negate("%in%")
# Using the same data as before
main_list <- list("apple", 5, c(11, 21), list("a", "b"))
search_vector <- c("apple", "banana", 5)
search_list <- list("apple", "banana", 5, c(11, 21))
# --- Vector %!in% List ---
search_vector %!in% main_list
# Output: [1] FALSE TRUE FALSE
# --- List %!in% List ---
list("apple", c(11, 2)) %!in% main_list
# Output: [1] FALSE TRUE
First, we are searching for a vector that is not on that list. Now, “apple” is there in the list, so not in operator will return FALSE. Banana is not on the list, so it returns TRUE, and 5 is on that list, so FALSE. And hence, the output is [1] FALSE TRUE FALSE.
The same is true for searching a list in another list. The apple element is present in the main_list, so it returns FALSE. Another element vector (11, 2) does not appear in the main_list, so it returns TRUE.

Krunal Lathiya is a seasoned Computer Science expert with over eight years in the tech industry. He boasts deep knowledge in Data Science and Machine Learning. Versed in Python, JavaScript, PHP, R, and Golang. Skilled in frameworks like Angular and React and platforms such as Node.js. His expertise spans both front-end and back-end development. His proficiency in the Python language stands as a testament to his versatility and commitment to the craft.