x
和一个向量v
。我想在v
中找到等于x
的元素的第一个索引。我知道执行此操作的一种方法是:which(x == v)[[1]]
,但这似乎效率太低。有更直接的方法吗?对于积分,如果
x
是向量,是否存在可以使用的函数?也就是说,它应该返回一个索引向量,指示x
中每个元素在v
中的位置。#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
。评论
我认为具有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))不需要更长的第一向量,并且实例之间有很多变化。还值得注意的是,它们对不匹配的处理方式非常不同。
–约翰
2011年4月7日13:30
@John:没错,但这不是OP要求的。 OP要求从一个长向量开始,查找另一个元素中给定的元素的第一个匹配项。为了完整起见,我补充说,如果您对所有索引都感兴趣,则必须使用which(%in%)。顺便说一句,没有理由删除您的答案。这是有效信息。
– Joris Meys
2011年4月7日13:36
我想强调一点,如果您想要第一次出现的索引,则匹配中参数的顺序很重要。对于您的示例,match(x,c(4,8))给出不同的结果,起初并不十分明显。
– apitsch
17年6月11日在9:20
@goldenoslik如果您阅读比赛的帮助页面,它将对您有帮助。一切都在那里解释。但是我添加了那条信息。
– Joris Meys
17年6月11日在10:14
#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]]吗?
–马库斯
19年11月20日在20:17
@markus此代码which(“ Feb” == month.abb)[[1]]返回“ 2”,并且此代码which(month.abb%in%“ Feb”)也返回“ 2”。另外,不清楚为什么使用向量没有意义
–安德里
19年11月21日在16:48
它与向量无关,而与向量的长度有关。您应该生成适当长度的向量,然后根据该向量进行基准测试。引用OP的问题“我知道实现此目的的一种方法是:which(x == v)[[1]],但这似乎效率太低。”
–马库斯
19年11月21日在22:05
评论
由于R已针对与矢量一起使用进行了优化,因此(x == v)[[1]]效率不是很高。这是一个应用于所有矢量元素的比较(==)运算符,并且是索引(其中)的一个子集。而已。只要您没有在此函数上运行10.000次重复,就没有关系了。其他解决方案(例如匹配和排名)可能不会返回那么多的数据,但不一定能提高效率。我的问题指定我希望对x进行矢量化的函数,而对(x == v)[[1]]不是。