在R语言中,是否有一种函数可以找到向量中元素的索引?

427

在R语言中,我有一个元素x和一个向量v。我想要找到向量v中第一个等于x的元素的索引。我知道一种做法是:which(x == v)[[1]],但这似乎过于低效。有没有更直接的方法?

如果x是一个向量,是否有函数可以返回x中每个元素在v中的位置索引向量?


2
由于R被优化为与向量一起使用,因此which(x == v)[[1]]并不是非常低效的。这是一个比较(==)运算符应用于所有向量元素和一个索引子集(which)。就这些。只要您不在此函数上运行10,000次重复,那么这些都不应该是相关的。其他解决方案,如matchPosition可能不会返回与which一样多的数据,但它们不一定更有效。 - BurninLeo
6
我的问题中指定了我更倾向于一个能够在x上进行向量化的函数,而which(x == v)[[1]]不能。请你翻译该句话。 - Ryan C. Thompson
新问题占位符: - berriz44
4个回答

589

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


1
我认为使用c(2,3,3)和c(1,2,3,4)的示例,同时使用match和%in%会更具指导性,并且在示例之间的更改较少。 match(c(2,3,3), c(1:4))返回的结果与which(c(2,3,3) %in% c(1:4))不同,而无需一个更长的第一个向量和许多示例之间的更改。值得注意的是,它们处理非匹配的方式也有很大不同。 - John
1
@John: 都是正确的,但这不是 OP 提出的问题。OP 的问题是从一个长向量开始,在另一个向量中查找第一个匹配的元素。为了完整起见,我补充说,如果你想要所有索引,你将不得不使用 which(%in%)。顺便说一句,没有理由删除你的答案。它是有效的信息。 - Joris Meys
3
我认为强调一下match函数中参数的顺序对于想要获得第一个匹配项的索引非常有帮助。以你的例子为例,match(x,c(4,8))会得到不同的结果,而这一点一开始可能并不是非常明显。 - apitsch
@ goldenoslik 如果您阅读“match”的帮助页面,将会有所帮助。所有内容都在那里解释了。但我添加了这一信息。 - Joris Meys

33

在funprog {base}中,函数Position也可以完成此任务。它允许您传递任意函数,并返回第一个或最后一个匹配项。

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


19

关于上述方法的效率,有一个小提示:

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

2
你的基准是基于一个长度为12的向量,因此没有意义。另外,在你的例子中 which("Feb" == month.abb) 返回 2 - 为什么要加上 [[1]] - markus
1
@markus 这段代码 which("Feb" == month.abb)[[1]] 返回 "2",而这段代码 which(month.abb %in% "Feb") 也返回 "2"。另外,不清楚为什么使用向量没有意义。 - Andrii
4
重点不在于向量本身,而在于其长度。你需要生成一个合适长度的向量,然后基于此进行基准测试。引用原问题中的话:“我知道一种方法是使用 which(x == v)[[1]],但这似乎非常低效。” - markus

15

是的,我们可以按以下方式在向量中找到元素的索引:

> a <- c(3, 2, -7, -3, 5, 2)
> b <- (a==-7)  # this will output a TRUE/FALSE vector
> c <- which(a==-7) # this will give you numerical value
> a
[1]  3  2 -7 -3  5  2
> b
[1] FALSE FALSE  TRUE FALSE FALSE FALSE
> c
[1] 3

这是一种在向量中查找元素索引的最有效方法之一。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接