【问题标题】:Is there a way or alternative function to have a vectorized str_detect() in R?有没有一种方法或替代函数可以在 R 中使用矢量化 str_detect() ?
【发布时间】:2021-06-11 11:00:43
【问题描述】:

我有一个包含一列字符串的数据框,我尝试过滤掉其中包含日期的字符串。

ID headline SOURCE domain
21 Cool text with a date 20.01.2009 0 howtomakelessthanminimumwagebybuyingthisbook.com
22 not so cool text without date 0 lars.com
23 also a cool text but without a date :( 0 somecryptostuff.com
24 long text with a date like this 3. march 2021 0 blockchainmasterclassforpeoplewithouttechnicalbackground.com
25 other long text with this kind of date in the text 03/21/99 and other stuff afterwards 0 someother.url

我已经编写了这样做的代码。

首先,我使用 str_detect() 过滤所有包含日期​​的行的 df。

代码如下所示:

data <- origin%>%
  filter(str_detect(headline, yyyy_mm_dd)|
         str_detect(headline, mm_dd_yyyy)|
         str_detect(headline, mm_dd_yy)|
         str_detect(headline, dd_mm_yyyy)|
         str_detect(headline, dd_mm_yy)|
         str_detect(headline, annoying_dates)|
         str_detect(headline, monthnum_year)|
         str_detect(headline, monthname_year)|
        str_detect(headline," 20(1|2)\\d\\s"))

mm_dd_yyyy 等是我分配正则表达式的变量。它们看起来像最后一行。

我的代码工作正常,但我经常使用这些过滤条件,重复使用一个函数有点烦人,而且肯定不是好习惯。

我试图想出一个更好的解决方案,但最终未能如愿。你们有什么想法吗?我想过使用一个可以循环的矢量槽,但我不知道这是否可以使用str_detect

【问题讨论】:

  • 您可以将各个正则表达式组合成一个表达式,方法是将每个单独的表达式包装成(…) 并用| 分隔符连接它们。
  • @KonradRudolph 我之前尝试过,但这样做有很多不合理的问题。出于某种原因,拆分正则表达式修复了无法正确匹配的错误。我在 regex101 上对其进行了测试,它可以工作,但使用 r 时它被破坏了
  • 您能否显示共享数据的预期输出?此外,如果您创建一个可以直接复制到 R 中的小型可重复示例,这将更容易提供帮助。阅读how to give a reproducible example
  • str_detect 已矢量化,标题不准确

标签: r dplyr stringr


【解决方案1】:

如果您使用{tidyverse} 家族,请注意{lubridate} 有一个非常强大的功能:parse_date_time()。后者方便地从任意字符串中“提取”日期。

数据

library(tibble)
ds <- tibble::tribble(
  ~ID,  ~headline, ~SOURCE, ~domain
,  21L, "Cool text with a date 20.01.2009", 0L,             "howtomakelessthanminimumwagebybuyingthisbook.com",
  22L, "not so cool text without date", 0L, "lars.com",
  23L, "also a cool text but without a date :(", 0L, "somecryptostuff.com",
  24L, "long text with a date like this 3. march 2021", 0L, "blockchainmasterclassforpeoplewithouttechnicalbackground.com",
  25L, "other long text with this kind of date in the text 03/21/99 and other sutff afterwards", 0L, "someother.url"
  )

解析日期(时间)

library(dplyr)
library(lubridate)

ds %>% 
  mutate(
    DATE  = lubridate::parse_date_time(headline, orders = c("dmy","mdy"))
  , DATE2 = lubridate::parse_date_time(headline, orders = c("dmy","mdy")) %>%    
                                         as.Date() #if you want a "date" only
  ) %>% 
select(headline, DATE, DATE2)

{lubridate} 将针对没有日期的标题发出警告,说明它无法解析该标题(没有日期)。您可以将其包装到处理 NA 案例的调用中。

这就是你得到的:

# A tibble: 5 x 3
  headline                                                                               DATE                DATE2     
  <chr>                                                                                  <dttm>              <date>    
1 Cool text with a date 20.01.2009                                                       2009-01-20 00:00:00 2009-01-20
2 not so cool text without date                                                          NA                  NA        
3 also a cool text but without a date :(                                                 NA                  NA        
4 long text with a date like this 3. march 2021                                          2021-03-03 00:00:00 2021-03-03
5 other long text with this kind of date in the text 03/21/99 and other sutff afterwards 1999-03-21 00:00:00 1999-03-21

【讨论】:

    【解决方案2】:

    您可以使用| 分隔符粘贴所有正则表达式或使用循环函数:

    reduce(purrr:map(c(regex1, regex2, ..., " 20(1|2)\\d\\s"), str_detect(.x, headline))), `|`)
    
    str_detect(headline, paste(regex1, regex2, ..., " 20(1|2)\\d\\s"), collapse="|")
    

    【讨论】:

      猜你喜欢
      • 2021-11-16
      • 1970-01-01
      • 1970-01-01
      • 2020-09-08
      • 1970-01-01
      • 2014-02-05
      • 1970-01-01
      • 2021-12-11
      • 2014-01-25
      相关资源
      最近更新 更多