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


518

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


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

как насчет того, чтобы получить все появления, а не только первый?
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 () из списка по причине, указанной в комментариях


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))]

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

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


10
По умолчанию grepв качестве первого элемента используется регулярное выражение, поэтому для точного соответствия "b"либо используйте, ^e$либо добавьте , fixed=TRUE).
reinierpost

10
Не используйте регулярные выражения для точных совпадений. Это опасно и может привести к неожиданным результатам
Дэвид Аренбург

9
Да, это ужасная, бесполезная, очень плохая идея - неэффективная и гарантированно сломанная. Например myvar <- 'blah'; grepl('b', myvar, fixed=TRUE), вернется, TRUEдаже если «б» не в myvar.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.