【问题标题】:Test if a vector contains a given element测试向量是否包含给定元素
【发布时间】:2010-11-13 05:52:53
【问题描述】:

如何检查向量是否包含给定值?

【问题讨论】:

  • 有时我会问自己为什么 R 不使用包含这个词来让用户更容易使用
  • 认为“in”包含在“conta(in)s”中;我认为“in”在这种情况下是一个相当简洁的竞争者
  • 也许加上侧翼%-signs 就是这样。单词in 是 R 中用于 for 循环构造的保留字。
  • @greg121 dplyr 已经有一个contains 函数,但它用于不同的目的:在数据框中选择一列。例如select(iris, contains("etal")).
  • 对于具有给定精度的实数值,是否有一种简洁的方法?

标签: r vector r-faq


【解决方案1】:

match()(返回第一次出现)和%in%(返回布尔值)函数都是为此而设计的。

v <- c('a','b','c','e')

'b' %in% v
## returns TRUE

match('b',v)
## returns the first location of 'b', in this case: 2

【讨论】:

  • 如何获得所有出场,而不仅仅是第一个?
  • 也许我来的有点晚。 which(v, 'b')。注意参数的顺序。
  • 你的which(v, 'b') 给了我一个错误信息:>Error in which(v, 'b') : argument to 'which' is not logical
  • 语法是 which(v == b) 或任何其他逻辑运算符。在这种情况下, this 的返回值为 2。如果 v 是 c("b", "b", "c", "b", "d"),返回 which(v == b) 将是1、2、4。
【解决方案2】:

is.element() 使代码更具可读性,与%in% 相同

v <- c('a','b','c','e')

is.element('b', v)
'b' %in% v
## both return TRUE

is.element('f', v)
'f' %in% v
## both return FALSE

subv <- c('a', 'f')
subv %in% v
## returns a vector TRUE FALSE
is.element(subv, v)
## returns a vector TRUE FALSE

【讨论】:

  • 我知道文档说is.element(x, y) is identical to x %in% y。但是,我不知道为什么,is.elements 在混合整数和数字时有效,而 %in% 无效
  • @pomber:你能举个例子吗?
  • @pomber 修复了吗?
  • is.element()%in% 的优越可读性是主观的。可以使中缀运算符更具可读性,因为它消除了参数顺序的歧义。 apple in fruit 有道理,fruit in apple 没有。 is.element(apple, fruit)is.element(fruit, apple) 都可能是正确的,具体取决于 is.element 函数的实现。
【解决方案3】:

我将根据输出对选项进行分组。假设所有示例都使用以下向量。

v <- c('z', 'a','b','a','e')

用于检查存在:

%in%

> 'a' %in% v
[1] TRUE

any()

> any('a'==v)
[1] TRUE

is.element()

> is.element('a', v)
[1] TRUE

寻找第一次出现:

ma​​tch()

> match('a', v)
[1] 2

用于查找所有出现的索引向量:

哪个()

> which('a' == v)
[1] 2 4

用于查找所有出现的逻辑向量

==

> 'a' == v
[1] FALSE  TRUE FALSE  TRUE FALSE

编辑: 由于 cmets 中提到的原因,从列表中删除 grep()grepl()

【讨论】:

  • 正如已经评论过的herehere,不要使用grep() 或正则表达式来查找精确匹配项。
【解决方案4】:

any() 函数使代码可读

> w <- c(1,2,3)
> any(w==1)
[1] TRUE

> v <- c('a','b','c')
> any(v=='b')
[1] TRUE

> any(v=='f')
[1] FALSE

【讨论】:

  • 请注意,这与%in% 的行为不同:any(1==NA) 返回NA,其中1 %in% NA 返回FALSE
  • @user3603486: any(1==NA, na.rm=TRUE) 返回FALSE
【解决方案5】:

您可以使用%in% 运算符:

vec <- c(1, 2, 3, 4, 5)
1 %in% vec # true
10 %in% vec # false

【讨论】:

    【解决方案6】:

    也可以找到元素“which”的位置

    pop <- c(3,4,5,7,13)
    
    which(pop==13)
    

    要找到目标向量中不包含的元素,可以这样做:

    pop <- c(1,2,4,6,10)
    
    Tset <- c(2,10,7)   # Target set
    
    pop[which(!(pop%in%Tset))]
    

    【讨论】:

    • which 实际上有时更可取,因为它为您提供 all 匹配位置(作为一个数组),这与 match 不同。尽管这可能不是 OP 所要求的,但与 stackoverflow.com/questions/1169388/… 不同
    • 如果您只想找到不在Tset 中的元素,为什么还要麻烦which?您可以直接索引poppop[!pop%in%Tset]
    【解决方案7】:

    为此我非常喜欢 grep() 和 grepl()。

    grep() 返回一个整数向量,表示匹配的位置。

    yo <- c("a", "a", "b", "b", "c", "c")
    
    grep("b", yo)
    [1] 3 4
    

    grepl() 返回一个逻辑向量,匹配位置为“TRUE”。

    yo <- c("a", "a", "b", "b", "c", "c")
    
    grepl("b", yo)
    [1] FALSE FALSE  TRUE  TRUE FALSE FALSE
    

    这些函数区分大小写。

    【讨论】:

    • 默认情况下,grep 将正则表达式作为其第一个元素,因此要对"b" 进行精确匹配,请使用^e$ 或添加, fixed=TRUE
    • 不要使用正则表达式进行精确匹配。这很危险,可能会产生意想不到的结果
    • 是的,这是一个糟糕的、不好的、非常糟糕的想法 - 效率低下并且保证会中断。例如。 myvar &lt;- 'blah'; grepl('b', myvar, fixed=TRUE) 将返回 TRUE,即使 'b' 不在 myvar 中。
    猜你喜欢
    • 1970-01-01
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多