假设我有以下向量:
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
|
运算符来简化条件语句。which(x == 8 | x == 9)
# 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
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),则对于两者输出将是相同的。这种方法缓解了这种问题。
> 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
grepl
可能是一个有用的函数。请注意,grepl
出现在 R 2.9.0 及更高版本中。 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)
||
,这是错误的语法。 - atomiculesgrepl(9, c(9, 99, 654649))
将会对所有这些值返回 TRUE
。在使用精确匹配和正则表达式时应该非常小心。 - David Arenburg
duplicated
,你可以使用duplicated(x) | duplicated(x, fromLast=T)
来获取所有重复值。 - smci