是否有用于查找向量中元素索引的 R 函数?

Posted

技术标签:

【中文标题】是否有用于查找向量中元素索引的 R 函数?【英文标题】:Is there an R function for finding the index of an element in a vector? 【发布时间】:2011-07-31 11:13:36 【问题描述】:

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

对于奖励积分,如果x 是一个向量,是否有一个函数可以工作?也就是说,它应该返回一个索引向量,指示x 的每个元素在v 中的位置。

【问题讨论】:

由于 R 已针对向量进行了优化,which(x == v)[[1]] 并不是那么低效。这是一个应用于所有向量元素的比较 (==) 运算符和索引上的一个子集 (which)。而已。只要您没有在此功能上运行 10.000 次重复,就没有什么相关的。 matchPosition 等其他解决方案返回的数据可能不如 which 多,但它们不一定更有效。 我的问题表明我更喜欢在 x 上进行矢量化的函数,而 which(x == v)[[1]] 不是。 所以这是我在 SO 上提出问题时首先看到的内容 【参考方案1】:

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

【讨论】:

我认为带有匹配和 %in% 的 c(2,3,3) 和 c(1,2,3,4) 的示例会更具指导性,示例之间的更改更少. match(c(2,3,3), c(1:4)) 从 which(c(2,3,3) %in% c(1:4)) 返回不同的结果,而不需要更长的第一个向量,并且从示例到示例的许多变化。还值得注意的是,它们处理不匹配的方式非常不同。 @John :这都是真的,但这不是 OP 所要求的。 OP 从一个长向量开始要求找到另一个给定元素的第一个匹配项。为了完整起见,我补充说,如果您对所有索引感兴趣,则必须使用 which(%in%)。顺便说一句,没有理由删除您的答案。这是有效的信息。 我认为如果您想要第一次出现的索引,强调match 中参数的顺序很重要。对于您的示例,match(x,c(4,8)) 给出了不同的结果,一开始并不是很明显。 @goldenoslik 如果您阅读match 的帮助页面,它会有所帮助。这一切都在那里解释。但我添加了那条信息。【参考方案2】:

funprog base 中的函数Position 也可以完成这项工作。它允许您传递任意函数,并返回第一个或最后一个匹配项。

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

【讨论】:

【参考方案3】:

关于上述方法效率的小记:

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

【讨论】:

您的基准测试基于长度为 12 的向量,因此没有意义。同样在您的示例中which("Feb" == month.abb) 返回2–为什么[[1]] @markus 这个代码 which("Feb" == month.abb)[[1]] return "2",这个代码 which(month.abb %in% "Feb") 也返回“2”。另外,不清楚为什么使用向量没有意义 这不是关于向量,而是关于它的长度。您应该生成一个适当长度的向量,然后在此基础上进行基准测试。引用 OP 的问题 “我知道这样做的一种方法是: which(x == v)[[1]], 但这似乎效率极低。”【参考方案4】:

是的,我们可以在向量中找到一个元素的索引,如下所示:

> 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

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

【讨论】:

以上是关于是否有用于查找向量中元素索引的 R 函数?的主要内容,如果未能解决你的问题,请参考以下文章

获取R向量中的所有最大值索引

R:如何在不使用循环的情况下按唯一向量顺序查找所有重复向量值的索引?

在 C++ 矩阵中查找最大元素的索引?

在 CoreData 的 NSOrderedSet 中查找对象。索引(无障碍元素:)

r语言match函数怎么用

如何沿向量 C++ 的长度找到数字的索引?