r - 如何使用正则表达式提取 case_when 语句中的特定字符串模式?

标签 r regex stringr

考虑一下我根据 Donald Trump-Tweets 数据集(可以在 here 找到)创建的以下可重现数据集:

df <- tibble(target = c(rep("jeb-bush", 2), rep("jeb-bush-supporters", 2),
                        "jeb-staffer", rep("the-media", 5)),
             tweet_id = seq(1, 10, 1))

它由两列组成,推文的目标组和tweet_id:

# A tibble: 10 x 2
   target              tweet_id
   <chr>                  <dbl>
 1 jeb-bush                   1
 2 jeb-bush                   2
 3 jeb-bush-supporters        3
 4 jeb-bush-supporters        4
 5 jeb-staffer                5
 6 the-media                  6
 7 the-media                  7
 8 the-media                  8
 9 the-media                  9
10 the-media                 10

目标:

每当 target 中的元素以 jeb 开头时,我想提取 - 之后的字符串模式。每当以 jeb 开头的元素中有多个 - 时,我想提取最后一个 - 之后的字符串模式(在此示例数据集仅适用于 jeb-bush-supporters)。对于每个不以 jeb 开头的元素,我只想创建字符串 other。 最后,它应该看起来像这样:

# A tibble: 10 x 3
   target              tweet_id new_var   
   <chr>                  <dbl> <chr>     
 1 jeb-bush                   1 bush      
 2 jeb-bush                   2 bush      
 3 jeb-bush-supporters        3 supporters
 4 jeb-bush-supporters        4 supporters
 5 jeb-staffer                5 staffer   
 6 the-media                  6 other     
 7 the-media                  7 other     
 8 the-media                  8 other     
 9 the-media                  9 other     
10 the-media                 10 other    

我尝试过的:

我实际上已经成功地使用以下代码创建了所需的输出:

df %>% 
    mutate(new_var = case_when(str_detect(target, "^jeb-[a-z]+$") ~
                             str_extract(target, "(?<=[a-z]{3}-)[a-z]+"),
                               str_detect(target, "^jeb-[a-z]+-[a-z]+") ~
                             str_extract(target, "(?<=[a-z]{3}-[a-z]{4}-)[a-z]+"),
                               TRUE ~ "other"))

但问题是这样的:

在第二个 str_extract 语句中,我必须定义“Positive Look Behind”中的确切字母数量 ([a-z]{4})。否则,R 会提示需要“有限的最大长度”。但是,如果我不知道确切的模式长度或者它会因元素而异怎么办?

或者,我尝试使用捕获组而不是“环顾四周”。因此,我尝试包含 str_match 来定义我想要提取的内容,而不是我不想提取的内容:

df %>% 
    mutate(new_var = case_when(str_detect(target, "^jeb-[a-z]+$") ~
                             str_match(target, "jeb-([a-z]+)"),
                           str_detect(target, "^jeb-[a-z]+-[a-z]+") ~
                             str_match(target, "jeb-[a-z]+-([a-z]+)"),
                           TRUE ~ "other"))

但随后我收到此错误消息:

Error: Problem with `mutate()` input `new_var`.
x `str_detect(target, "^jeb-[a-z]+$") ~ str_match(target, "jeb-([a-z]+)")`, `str_detect(target, "^jeb-[a-z]+-[a-z]+") ~ str_match(target, 
    "jeb-[a-z]{4}-([a-z]+)")` must be length 10 or one, not 20.
i Input `new_var` is `case_when(...)`.

问题:

最终,我想知道是否有一种简洁的方法可以在 case_when 语句中提取特定的字符串模式。当我无法使用“Look arounds”(因为我无法定义有界的最大长度)或捕获组(因为 str_match会返回一个长度为 20 的向量,而不是原始大小为 10 或 1)?

最佳答案

一个选项是从 case_when 中的字符串开头 (^) 检查目标列中是否包含“jeb-”子字符串,然后提取不存在的字符字符串末尾 ($) 处的 - ([^-]+),或者 (TRUE) >) 返回“其他”

library(dplyr)
library(stringr)
df %>% 
    mutate(new_var = case_when(str_detect(target, '^jeb-')~ 
        str_extract(target, '[^-]+$'), TRUE ~ 'other'))

-输出

# A tibble: 10 x 3
#   target              tweet_id new_var   
#   <chr>                  <dbl> <chr>     
# 1 jeb-bush                   1 bush      
# 2 jeb-bush                   2 bush      
# 3 jeb-bush-supporters        3 supporters
# 4 jeb-bush-supporters        4 supporters
# 5 jeb-staffer                5 staffer   
# 6 the-media                  6 other     
# 7 the-media                  7 other     
# 8 the-media                  8 other     
# 9 the-media                  9 other     
#10 the-media                 10 other    

我们还可以使用 str_matchcoalesce 来简化此过程

df %>% 
   mutate(new_var = coalesce(str_match(target, '^jeb-.*?([^-]+)$')[,2], 'other')) 

关于r - 如何使用正则表达式提取 case_when 语句中的特定字符串模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66894270/

相关文章:

javascript - 用于检查文本字段值是否以 "["开头的正则表达式

r - 合并为 gregexpr 输出的一个字符串的更简单方法?

r - 如何指示第一个事件观察并删除纵向数据框中其余的事件观察?

wolfram alpha的R接口(interface)

java - 在Java中使用正则表达式解析字符串行

python - 仅匹配字符串中的单词列表

r - 如何从电话号码中提取国家代码?

regex - 与 R 中的 str_locate 正则表达式完全匹配

r - 变异更改整列而不是逐行更改

r - 如何选择数字后缀小于某个值的变量