提问人:Christopher DuBois 提问时间:7/23/2009 最后编辑:JaapChristopher DuBois 更新时间:4/18/2022 访问量:45136
查找向量中多个元素的所有位置
Finding All Positions for Multiple Elements in a Vector
问:
假设我有以下向量:
x <- c(8, 6, 9, 9, 7, 3, 2, 5, 5, 1, 6, 8, 5, 2, 9, 3, 5, 10, 8, 2)
如何找到哪些元素是 8 或 9?
答:
这是一种方法。首先,我得到 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
评论
或者,如果您不需要使用索引,而只需要使用元素,则可以执行
> 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
您可以在短时间内尝试运算符|
which(x == 8 | x == 9)
grepl
也许是一个有用的功能。请注意,出现在 R 2.9.0 及更高版本中。方便的是,它返回一个长度与 相同的逻辑向量。grepl
grepl
x
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)
评论
||
grepl(9, c(9, 99, 654649))
TRUE
在这种特定情况下,您还可以使用: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)
1
10
> grep('1|8',x)
[1] 1 10 12 18 19
为了避免这种副作用,您必须将要检测的数字包装在单词边界中:
> grep('\\b1\\b|8',x)
[1] 1 10 12 19
现在,未检测到。10
这是一个通用解决方案,用于查找所有目标值的位置(仅适用于向量和一维数组)。
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
评论
如果你想使用循环找到答案,那么下面的脚本将完成这项工作:
> 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),则两者的输出将相同。这种方法缓解了这样的问题。
上一个:删除子集数据框中未使用的因子水平
下一个:测试向量是否包含给定元素
评论
duplicated