【问题标题】:using grepl * to return NA values in R dplyr使用 grepl * 返回 R dplyr 中的 NA 值
【发布时间】:2022-01-15 04:09:30
【问题描述】:

我有一个具有 NA 值的数据集。我通过传递搜索字符串使用 grepl 进行过滤,并且一直希望使用“*”来返回所有值。

df <- structure(list(`Subject description` = c("Art & Design", "Chinese", 
"Classical Greek", "D&T Product Design", "Drama & Theatre Studies"
), `Discount code` = c(NA_character_, NA_character_, NA_character_, 
NA_character_, NA_character_)), row.names = c(NA, -5L), class = c("tbl_df", 
"tbl", "data.frame"))

search <- "*"

df %>% filter(grepl(search, `Discount code`))

以上返回一个空数据框。 grepl 有没有办法返回 NA 值。我很感激我可以用is.na(Discount code) 过滤器OR,但是我的代码正在使用搜索字符串,并且如果向string 提供另一个值,我不想返回 na 值

【问题讨论】:

  • 如果内容为 NA 或匹配您的搜索模式,您希望过滤器返回值?
  • 我想要两个功能,我希望“*”会返回包括 NA 在内的每一行,并且其他正则表达式值不会返回正在搜索的内容

标签: r dplyr grepl


【解决方案1】:

由于 grepl 只返回 TRUE 或 FALSE,您可以将 is.na 和您的 grepl 语句结合起来:

search <- "b"

df %>% filter(is.na(`Discount code`) | grepl(search, `Discount code`))

【讨论】:

  • 但是不管搜索字符串是什么,这不会返回NAs 吗?是否认为如果搜索模式是 "b" 则不应选择 NA 行。
  • 是的,但据我了解,他有一个空结果,这是仅使用 grepl 所期望的,因此我认为他想返回与 grepl 匹配的值,但也返回等于 NA 的值
【解决方案2】:

您可以将NAs 替换为""。然后您可以使用搜索字符串通过查找"*" 来返回所有行:

library(dplyr)
library(tidyr)

df %>%
  replace_na(list("Discount code" = "")) %>%  
    filter(grepl("*", `Discount code`))

#> # A tibble: 5 x 2
#>   `Subject description`   `Discount code`
#>   <chr>                   <chr>          
#> 1 Art & Design            ""             
#> 2 Chinese                 ""             
#> 3 Classical Greek         ""             
#> 4 D&T Product Design      ""             
#> 5 Drama & Theatre Studies ""

reprex package (v2.0.1) 于 2021 年 12 月 10 日创建

【讨论】:

    【解决方案3】:

    我最终创建了一个自定义函数来执行此操作:

    greplna <- function(data, reg="*", var="Discount code"){
      if(reg == "*"){
        tmp <- grepl("*", as.list(data[var])[[1]]) | is.na(as.list(data[var])[[1]])
      }else{
        tmp <- grepl(reg, as.list(data[var])[[1]])
      }
      return(tmp)
    }
    

    然后您可以在 dplyr 语句中使用它:

    df %>% filter(greplna(., search, "Discount code"))
    

    但不要在分组后使用它,因为. 获取整个数据集,而不是分组数据集

    【讨论】:

    • 这也是一个不错的选择。您可以使用{{ }}ifelse 来简化函数:function(x = "Discount code", reg="*"){ ifelse(reg == "*", (grepl("*", {{ x }}) | is.na({{ x }})), grepl(reg, {{ x }}))}
    • 我之前没见过{{}}。它有什么不同?
    • 它使函数与列名(符号)一起工作,在这种情况下我们不需要数据参数。在“间接”下的programming with dplyr vignette 中有解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-04
    • 1970-01-01
    • 2019-05-05
    • 2018-06-05
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    相关资源
    最近更新 更多