【问题标题】:Filter dataframe in R on occurrence of multiple patterns in a string在字符串中出现多个模式时过滤R中的数据框
【发布时间】:2021-04-01 00:43:43
【问题描述】:

数据

我有一个数据框,其中有一列由 R 中的字符串组成。

data <- structure(list(col = c("byr:1985 eyr:2021 iyr:2011 hgt:175cm pid:163069444 hcl:#18171d", 
                       "eyr:2023 hcl:#cfa07d ecl:blu hgt:169cm pid:494407412 byr:1936", 
                       "ecl:zzz eyr:2036 hgt:109 hcl:#623a2f iyr:1997 byr:2029 cid:169 pid:170290956", 
                       "hcl:#18171d ecl:oth pid:266824158 hgt:168cm byr:1992 eyr:2021", 
                       "byr:1932 ecl:hzl pid:284313291 iyr:2017 hcl:#efcc98 eyr:2024 hgt:184cm"
)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"
))

问题

我想在包含以下模式/字段的行上过滤此数据框:

fields <- c("ecl", "eyr", "hgt", "hcl", "iyr", "byr", "pid")

换句话说,我想获得确实包含这些字段的行。

尝试

stringr 包和str_detect 函数似乎是解决方案!所以,我在一个案例上进行了测试:

> data$col[1]
[1] "byr:1985 eyr:2021 iyr:2011 hgt:175cm pid:163069444 hcl:#18171d"
> str_detect(data$col[1], fields)
[1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
> all(str_detect(data$col[1], fields))
[1] FALSE

这行得通!如果字符串中不存在任何字段,则将其评估为 false。

但是,当尝试使用此选项过滤行时:

data %>% 
    filter( all(str_detect(col, fields)) )

我最终得到一个空数据框和一个警告:

警告信息:在 stri_detect_regex(string, pattern, negate = negate, opts_regex = opts(pattern)) : 更长的对象长度不是 短物体长度的倍数

问题

  • 是什么导致了这个警告?
  • 如何在 R 中出现多个模式时过滤一列字符串?

【问题讨论】:

    标签: r string dataframe filter


    【解决方案1】:

    您收到警告的原因是因为str_detect 是矢量化函数,这意味着col 中的第一个值与fields 的第一个值匹配,第二个值与第二个匹配,依此类推。 col 的长度为 5,fields 的长度为 7,因此它们的长度不兼容,这就是警告的意思。

    要过滤datafields 的每个值都存在于base R 中的行,您可以这样做:

    data[Reduce(`&`, lapply(fields, grepl, data$col)), ]
    
    #  col                                                                         
    #  <chr>                                                                       
    #1 ecl:zzz eyr:2036 hgt:109 hcl:#623a2f iyr:1997 byr:2029 cid:169 pid:170290956
    #2 byr:1932 ecl:hzl pid:284313291 iyr:2017 hcl:#efcc98 eyr:2024 hgt:184cm      
    

    如果您对tidyverse 的回答感兴趣,您可以将以上内容写成:

    library(tidyverse)
    
    data %>% filter(map(fields, ~str_detect(data$col, .x)) %>% reduce(`&`))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-26
      • 2019-10-23
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      相关资源
      最近更新 更多