Отрицание% в% в R

Есть ли короткое отрицание %in% в R, например !%in% или %!in%?


Конечно, я могу отрицать c("A", "B") %in% c("B", "C") на !(c("A", "B") %in% c("B", "C")) (см. этот вопрос), но я бы предпочел более прямолинейный подойдите и сохраните пару скобок (похоже, что большинство людей предпочли бы c("A", "B") != c("B", "C") вместо !(c("A", "B") == c("B", "C"))).


person Qaswed    schedule 13.07.2016    source источник
comment
@SpencerCastro Я включил ссылку на вопрос, который вы упомянули. Мой вопрос в другом: я знаю о технических возможностях отрицания %in%. Мой вопрос о том, существует ли прямой подход или нет. И ответ, данный пользователем катастрофического отказа, говорящий «Нет, [...] но ...», был тем, что я хотел знать.   -  person Qaswed    schedule 26.02.2018
comment
Отлично, я думаю, что связывание этих вопросов полезно, потому что оба дают полное объяснение решений.   -  person Spencer Castro    schedule 26.02.2018


Ответы (4)


Нет, для этого нет встроенной функции, но вы можете легко запрограммировать ее самостоятельно с помощью

`%nin%` = Negate(`%in%`)

Or

`%!in%` = Negate(`%in%`)

См. эту ветку и последующее обсуждение: %in% оператор - НЕ В


Кроме того, было указано, что пакет Hmisc включает оператор %nin%, поэтому, если вы используете его для своих приложений, он уже есть.

library(Hmisc)
"A" %nin% "B"
#[1] TRUE
"A" %nin% "A"
#FALSE
person catastrophic-failure    schedule 13.07.2016
comment
Любопытно, почему эта функция существует, учитывая, что все, что она делает, буквально бросает ! перед своим аргументом. - person MichaelChirico; 13.07.2016
comment
! а также скобки. это экономия времени. 1 клавиша ‹ 3 клавиши плюс стрелки для создания скобок - person Canovice; 18.07.2021

Вы всегда можете создать его:

> `%out%` <- function(a,b) ! a %in% b

> 1:10 %out% 5:15
[1]  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE

В противном случае есть несколько похожая функция с setdiff, которая возвращает уникальные элементы a, которых нет в b:

> setdiff(1:10,5:15)
[1] 1 2 3 4
> setdiff(5:15,1:10)
[1] 11 12 13 14 15
person plannapus    schedule 13.07.2016
comment
Вы (точнее, OP) должны быть осторожны с использованием setdiff вместо инвертированного %in%, поскольку, как следует из названия, это операция set и, следовательно, возвращает только unique элементы a, которых нет в b. Это может сильно отличаться от отрицательного %in%. - person talat; 13.07.2016
comment
Правда, я отредактирую, чтобы сделать этот момент более ясным. Спасибо! - person plannapus; 13.07.2016

На самом деле вам не нужны дополнительные скобки, !c("A", "B") %in% c("B", "C") работает.

Если вы предпочитаете что-то, что читается проще, просто определите это самостоятельно:

"%nin%" <- function(x, table) match(x, table, nomatch = 0L) == 0L

Преимущество этого заключается в том, что усилия не тратятся впустую — мы не получаем результат, а затем отрицаем его, мы просто получаем результат напрямую. (разница вообще должна быть тривиальной)

person MichaelChirico    schedule 13.07.2016

Функция %!in% теперь доступна в library(operators)

person Reindert Van Herreweghe    schedule 14.11.2017
comment
Я только что попытался использовать это из пакета операторов. Пакеты, казалось, вызывали проблемы с dplyr::group_by(). Я не отлаживал его, но проблема исчезла, как только я удалил вызов библиотеки. - person BBlank; 04.04.2020