Проверить, содержит ли вектор данный элемент

518

Как проверить, содержит ли вектор заданное значение?

medriscoll
источник
38
иногда я спрашиваю себя, почему R просто не использует слово содержит, чтобы упростить его пользователям
greg121
12
считать, что "in" содержится в "conta (in) s"; Я бы сказал, что «в» является довольно кратким соперником в этом контексте
хеджировал и улучшал
1
Возможно с добавлением фланкирующих %знаков-то есть. Слово inявляется зарезервированным словом в R, используемом в конструкции цикла for.
IRTFM
@ greg121 dplyr уже есть содержит функцию, но она используется для различных целей: для выбора столбца в кадре данных. Например select(iris, contains("etal")).
Поль Ружье
Есть ли краткий способ сделать это для вещественных чисел с заданной точностью?
млт

Ответы:

500

Для этого предназначены функции match()(возвращает первое появление) и %in%(возвращает логическое значение).

v <- c('a','b','c','e')

'b' %in% v
## returns TRUE

match('b',v)
## returns the first location of 'b', in this case: 2
medriscoll
источник
как насчет того, чтобы получить все появления, а не только первый?
StatsSorceress
Может быть, я немного опоздал. which(v, 'b'), Следите за порядком аргументов.
Никлас Мерч
Вы which(v, 'b')получаете мне сообщение об ошибке:> Ошибка, в которой (v, 'b'): аргумент для 'которого' не логичен
Capt.Krusty
176

is.element() делает для более читабельного кода, и идентичен %in%

v <- c('a','b','c','e')

is.element('b', v)
'b' %in% v
## both return TRUE

is.element('f', v)
'f' %in% v
## both return FALSE

subv <- c('a', 'f')
subv %in% v
## returns a vector TRUE FALSE
is.element(subv, v)
## returns a vector TRUE FALSE
Джастин Нафе
источник
6
Я знаю, что в документации сказано is.element(x, y) is identical to x %in% y. Но я не знаю почему, is.elementsработает при смешивании целых и %in%
числовых значений
@Pomber: Не могли бы вы привести пример этого?
Discipulus
@ Pomber это исправлено?
vasili111
2
Превосходная читаемость is.element()против %in%субъективна. Можно привести аргумент в пользу того, что инфиксный оператор более читабелен, поскольку устраняет неоднозначность в порядке аргументов. apple in fruitимеет смысл, fruit in appleнет. is.element(apple, fruit)или is.element(fruit, apple)оба могут быть правы в зависимости от реализации is.elementфункции.
rileymcdowell
70

Я сгруппирую варианты, основанные на результатах. Предположим следующий вектор для всех примеров.

v <- c('z', 'a','b','a','e')

Для проверки наличия:

%в%

> 'a' %in% v
[1] TRUE

Любые()

> any('a'==v)
[1] TRUE

is.element ()

> is.element('a', v)
[1] TRUE

Для нахождения первого случая:

матч()

> match('a', v)
[1] 2

Для нахождения всех вхождений как вектора индексов:

который()

> which('a' == v)
[1] 2 4

Чтобы найти все вхождения как логический вектор :

==

> 'a' == v
[1] FALSE  TRUE FALSE  TRUE FALSE

Изменить: Удаление grep () и grepl () из списка по причине, указанной в комментариях

ishandutta2007
источник
6
Как уже отмечалось здесь и здесь , не используйте grep()или регулярные выражения для поиска точных совпадений.
Уве
69

Функция any () обеспечивает читабельность кода

> w <- c(1,2,3)
> any(w==1)
[1] TRUE

> v <- c('a','b','c')
> any(v=='b')
[1] TRUE

> any(v=='f')
[1] FALSE
Дэн Гольдштейн
источник
9
Имейте в виду, что это ведет себя иначе, чем %in%: any(1==NA)возвращается NA, где 1 %in% NAвозвращается FALSE.
@ user3603486: any(1==NA, na.rm=TRUE)возвращается FALSE.
AkselA
36

Вы можете использовать %in%оператор:

vec <- c(1, 2, 3, 4, 5)
1 %in% vec # true
10 %in% vec # false
АРС
источник
19

Также для нахождения позиции элемента «который» можно использовать как

pop <- c(3,4,5,7,13)

which(pop==13)

и чтобы найти элементы, которые не содержатся в целевом векторе, можно сделать это:

pop <- c(1,2,4,6,10)

Tset <- c(2,10,7)   # Target set

pop[which(!(pop%in%Tset))]
Armin
источник
whichна самом деле предпочтительнее иногда, поскольку он дает вам все совпадающие позиции (в виде массива), в отличие от match. Хотя, возможно, это было не то, о чем просил ОП, в отличие от stackoverflow.com/questions/1169388/…
Fizz,
2
Зачем беспокоиться, whichесли вы просто хотите найти элементы не в Tset? Вы можете просто индексировать popнапрямую; pop[!pop%in%Tset]
Houshalter
13

Мне действительно нравятся grep () и grepl () для этой цели.

grep () возвращает вектор целых чисел, которые указывают, где находятся совпадения.

yo <- c("a", "a", "b", "b", "c", "c")

grep("b", yo)
[1] 3 4

grepl () возвращает логический вектор с «TRUE» в месте совпадений.

yo <- c("a", "a", "b", "b", "c", "c")

grepl("b", yo)
[1] FALSE FALSE  TRUE  TRUE FALSE FALSE

Эти функции чувствительны к регистру.

ojdajuiceman
источник
10
По умолчанию grepв качестве первого элемента используется регулярное выражение, поэтому для точного соответствия "b"либо используйте, ^e$либо добавьте , fixed=TRUE).
reinierpost
10
Не используйте регулярные выражения для точных совпадений. Это опасно и может привести к неожиданным результатам
Дэвид Аренбург
9
Да, это ужасная, бесполезная, очень плохая идея - неэффективная и гарантированно сломанная. Например myvar <- 'blah'; grepl('b', myvar, fixed=TRUE), вернется, TRUEдаже если «б» не в myvar.