查找向量中多个元素的所有位置

Finding All Positions for Multiple Elements in a Vector

提问人:Christopher DuBois 提问时间:7/23/2009 最后编辑:JaapChristopher DuBois 更新时间:4/18/2022 访问量:45136

问:

假设我有以下向量:

x <- c(8, 6, 9, 9, 7, 3, 2, 5, 5, 1, 6, 8, 5, 2, 9, 3, 5, 10, 8, 2)

如何找到哪些元素是 8 或 9?

矢量 R-FAQ

评论

0赞 smci 8/17/2018
如果你的意思是“检测所有重复的元素”。R 有一个有用的 fn ,你可以用 duplicated(x) |复制(x, fromLast=T)duplicated

答:

42赞 Christopher DuBois 7/23/2009 #1

这是一种方法。首先,我得到 x 为 8 或 9 的索引。然后我们可以验证在这些指数上,x 确实是 8 和 9。

> inds <- which(x %in% c(8,9))
> inds
[1]  1  3  4 12 15 19
> x[inds]
[1] 8 9 9 8 9 8

评论

2赞 dasf 9/18/2017
但是,假设我正在寻找两个值的特定索引,而没有对它们的顺序进行排序。如果我在字母表中查找 Z 和 A 的索引,我如何获得“26, 1”而不是“1, 26”的结果?其中( 字母 %in% c( 'z', 'a' ) ) )
0赞 Lumin 1/25/2019
@dasf使用任何类型的,比如 bubblesort
0赞 Union find 5/9/2022
这应该是赞成的答案......
1赞 Yann Abraham 7/23/2009 #2

或者,如果您不需要使用索引,而只需要使用元素,则可以执行

> x <- sample(1:10,20,replace=TRUE)
> x
 [1]  6  4  7  2  9  3  3  5  4  7  2  1  4  9  1  6 10  4  3 10
> x[8<=x & x<=9]
[1] 9 9
11赞 mdsumner 7/23/2009 #3

您可以在短时间内尝试运算符|

which(x == 8 | x == 9)
-1赞 andrewj 7/27/2009 #4

grepl也许是一个有用的功能。请注意,出现在 R 2.9.0 及更高版本中。方便的是,它返回一个长度与 相同的逻辑向量。greplgreplx

grepl(8, x)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE

grepl(9, x)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
[13] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE

要得出答案,您可以执行以下操作

grepl(8,x) | grepl(9,x)

评论

0赞 atomicules 11/30/2010
我也喜欢 grepl,非常适合过滤文本字符串等上的数据帧。感谢 OR 示例 - 我以为它会这么简单,但我一直在尝试哪个是错误的语法。||
4赞 David Arenburg 4/10/2016
这是一个非常危险的解决方案。 将返回所有这些。人们应该非常小心精确匹配和正则表达式。grepl(9, c(9, 99, 654649))TRUE
2赞 Jaap 8/17/2018 #5

在这种特定情况下,您还可以使用:grep

# option 1
grep('[89]',x)
# option 2
grep('8|9',x)

两者都给出:

[1]  1  3  4 12 15 19

当您还想检测具有多个数字的数字时,首选第二个选项:

> grep('10|8',x)
[1]  1 12 18 19

但是,我确实在回答开始时强调了这个特定案例是有原因的。@DavidArenburg如前所述,这可能会导致意想不到的结果。例如,使用将同时检测和:grep('1|8',x)110

> grep('1|8',x)
[1]  1 10 12 18 19

为了避免这种副作用,您必须将要检测的数字包装在单词边界中:

> grep('\\b1\\b|8',x)
[1]  1 10 12 19

现在,未检测到。10

2赞 user3474009 2/20/2020 #6

这是一个通用解决方案,用于查找所有目标值的位置(仅适用于向量和一维数组)。

locate <- function(x, targets) {
    results <- lapply(targets, function(target) which(x == target))
    names(results) <- targets
    results
}

此函数返回一个列表,因为每个目标可能具有任意数量的匹配项,包括零。列表按目标的原始顺序排序(和命名)。

下面是一个正在使用的示例:

sequence <- c(1:10, 1:10)

locate(sequence, c(2,9))
$`2`
[1]  2 12

$`9`
[1]  9 19

评论

0赞 Dimitrios Zacharatos 8/20/2020
不错的函数,如果它返回一个向量会更好
0赞 Dimitrios Zacharatos 8/20/2020
locate <- function(x, targets) { results <- lapply(targets, function(target) which(x == target)) unlist(results) }
1赞 Debjyoti 4/18/2022 #7

如果你想使用循环找到答案,那么下面的脚本将完成这项工作:

> req_nos<- c(8,9)
> pos<-list()
> for (i in 1:length(req_nos)){
  pos[[i]]<-which(x==req_nos[i])}

输出将如下所示:

>pos
[[1]]
[1] 1 12 19
[[2]] 
[1] 3  4 15

这里,pos[[1]] 包含 8 的位置,pos[[2]] 包含 9 的位置。如果您使用 %in% 方法并更改元素的输入顺序,即 c(9,8) 而不是 c(8,9),则两者的输出将相同。这种方法缓解了这样的问题。