【问题标题】:apply multiple logical functions to string to obtain a single final logical vector将多个逻辑函数应用于字符串以获得单个最终逻辑向量
【发布时间】:2021-04-23 03:25:14
【问题描述】:

我正在寻找一种方法,将两个不同的逻辑条件(包含和排除语句)应用于字符串,并获得一个逻辑向量作为输出:

我可以用以下代码做到这一点:

library(purrr)
library(stringr)

fruits<-c('apple', 'banana', NA, 'orange and apple')

conditions<-list(detect=function(x)str_detect(x,'apple'),
                 exclude=function(x)str_detect(x,'orange', negate=TRUE))

解决方案 1:

map_lgl(fruits, ~c(conditions[[1]](.) & conditions[[2]](.)))
>[1]  TRUE FALSE    NA FALSE

解决方案 2:

Reduce("&", map(conditions, ~.(fruits)))
>[1]  TRUE FALSE    NA FALSE

这显然很冗长,因为我必须定义和调用这两个函数,然后使用两个循环(map() 和Reduce())。

不知道:
- 有一种更简单的方法来调用这两个函数,以使用某种类似 purrr 的合成器在一次调用中创建最终向量。

我试过了

I tried to use `fruits%>%str_detect(., 'apple') & str_detect(., 'orange, negate=TRUE)

但是失败了,得到了一个“òbject '。”未找到”声明

-有一个更简单的 regex/stringr 解决方案,可以避免调用两个不同的 str_detect 函数

建议?

【问题讨论】:

    标签: r regex purrr stringr


    【解决方案1】:

    您可以使用grepl 和一个正则表达式来做到这一点:

    fruits<-c('apple', 'banana', NA, 'orange and apple')
    grepl("^(?!.*\\borange\\b).*\\bapple\\b.*$", fruits, perl=TRUE)
    
    [1]  TRUE FALSE FALSE FALSE
    

    但是,我可能会在这里对grepl 进行两次单独的调用:

    grepl("\\bapple\\b", fruits) & !grepl("\\borange\\b", fruits)
    [1]  TRUE FALSE FALSE FALSE
    

    【讨论】:

    • 嗨,蒂姆,谢谢。请参阅我在 Ronak Shahs 答案中的评论。
    • 我喜欢正则表达式解决方案。我觉得正则表达式中的排除/否定经常令人困惑,但有时有这个选项很好。请查看您的答案将 NA 转换为 FALSE,有没有办法修复它?
    • 你可以使用:ifelse(is.na(fruits), NA, grepl("\\bapple\\b", fruits) &amp; !grepl("\\borange\\b", fruits))
    【解决方案2】:

    您存储conditions 的方式使循环(map 或Reduce)成为必要。你为什么将它存储在列表中?这些是向量化的函数,可以以向量化的方式应用。

    library(stringr)
    str_detect(fruits, 'apple') & str_detect(fruits, 'orange', negate = TRUE)
    #[1]  TRUE FALSE    NA FALSE
    

    【讨论】:

    • 我想要一个通用的方法,它可能会在多种情况下变得讨厌。我可以在线调用所有函数。这种列表方法让我更好地理解了代码的结构。我也可能在同一个脚本的许多地方使用这种结构,我正在寻找一致性。我也试图从数据和管道开始,比如水果 %>%...,这就是发出 purrr 建议的原因。感谢您的耐心等待
    • 你不能真正像这样fruits %&gt;% str_detect('apple') %&gt;% str_detect('orange', negate = TRUE)输出str_detect,因为第一个管道(str_detect('apple') )的输出是TRUE/FALSE值,而我们需要的是实际值,即fruit。使用 str_subset 有效,但我不确定这是否是您想要的。 fruits %&gt;% str_subset('apple') %&gt;% str_subset('orange', negate = TRUE)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-02
    • 2014-08-05
    • 2018-11-22
    • 2010-10-29
    相关资源
    最近更新 更多