首页 > 解决方案 > 在字符串中出现多个模式时过滤R中的数据框

问题描述

数据

我有一个数据框,其中有一列由 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")

换句话说,我想获得包含每个字段的

试图

stringrstr_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

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

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

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

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

警告消息:在 stri_detect_regex(string, pattern, negate = negate, opts_regex = opts(pattern)) 中:较长的对象长度不是较短对象长度的倍数

问题)

标签: rstringdataframefilter

解决方案


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

要过滤data每个值fields存在于基 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(`&`))

推荐阅读