Существует ли функция R для нахождения индекса элемента в векторе?

244

В R у меня есть элемент x и вектор v. Я хочу найти первый индекс элемента в v, который равен x. Я знаю, что один из способов сделать это: which(x == v)[[1]], но это кажется чрезмерно неэффективным. Есть ли более прямой способ сделать это?

Для бонусных очков существует ли функция, которая работает, если x - вектор? То есть, он должен возвращать вектор индексов, указывающий положение каждого элемента x в v.

  • 0
    Так как R оптимизирован для работы с векторами, which(x == v)[[1]] не так уж и неэффективно. Это один оператор сравнения ( == ), применяемый ко всем элементам вектора, и одно подмножество индексов ( which ). Вот и все. Ничего, что должно быть актуально, если вы не выполняете 10.000 повторений для этой функции. Другие решения , как match и Position не может возвращать столько данных , сколько which , но они не обязательно более эффективным.
  • 2
    В моем вопросе было указано, что я бы предпочел функцию, которая была векторизована над x, а which(x == v)[[1]] - нет.
Теги:
indexing
match
vectorization

4 ответа

360
Лучший ответ

Функция match работает на векторах:

x <- sample(1:10)
x
# [1]  4  5  9  3  8  1  6 10  7  2
match(c(4,8),x)
# [1] 1 5

match возвращает только первое совпадение в соответствии с запросом. Он возвращает позицию во втором аргументе значений в первом аргументе.

Для множественного соответствия %in% - путь:

x <- sample(1:4,10,replace=TRUE)
x
# [1] 3 4 3 3 2 3 1 1 2 2
which(x %in% c(2,4))
# [1]  2  5  9 10

%in% возвращает логический вектор до тех пор, пока первый аргумент, с TRUE, если это значение можно найти во втором аргументе и FALSE в противном случае.

  • 0
    Я думаю, что пример с c (2,3,3) и c (1,2,3,4) с соответствием и% в% был бы более поучительным с меньшим количеством изменений между примерами. Функция match (c (2,3,3), c (1: 4)) возвращает различные результаты, из которых (c (2,3,3)% в% c (1: 4)) без необходимости использовать более длинный первый вектор и как много изменений от примера к примеру. Стоит также отметить, что они обрабатывают несоответствия совсем по-другому.
  • 1
    @ Джон: это все правда, но это не то, что спросил ОП. ОП попросил, начиная с длинного вектора, найти первое совпадение элементов, приведенных в другом. А для полноты я добавил, что если вас интересуют все индексы, вам придется использовать какой (% в%). Кстати, нет причин удалять ваш ответ. Это действительная информация.
Показать ещё 3 комментария
19

функция Position в funprog {base} также выполняет задание. Он позволяет передавать произвольную функцию и возвращает первое или последнее совпадение.

Position(f, x, right = FALSE, nomatch = NA_integer)

7

Небольшое замечание об эффективности вышеперечисленных методов:

 library(microbenchmark)

  microbenchmark(
    which("Feb" == month.abb)[[1]],
    which(month.abb %in% "Feb"))

  Unit: nanoseconds
   min     lq    mean median     uq  max neval
   891  979.0 1098.00   1031 1135.5 3693   100
   1052 1175.5 1339.74   1235 1390.0 7399  100

Итак, лучший из них

    which("Feb" == month.abb)[[1]]
0

R перегрузил двойной оператор == с помощью метода поиска индекса иглы в векторной стоге сена. Он дает вектор logical, содержащий значения TRUE для каждого совпадения в стоге сена.

Пример:

haystack <- c(1, 2, 4, 3, 4)
needle <- 4
indices <- needle == haystack
indices
[1] 3  5
haystack[indices]
[1] 4  4

Он работает, если оба являются векторами и могут быть расширены для использования нескольких векторов.

  • 2
    Оператор == уже упоминался в моем вопросе как неэффективное решение, которое не работает с вектором игл.
  • 0
    «это работает, если оба являются векторами» - возможно, в зависимости от того, что вы имеете в виду ... но не в том смысле, в котором хотел ОП.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню