【问题标题】:dplyr filter columns with multiple regex具有多个正则表达式的 dplyr 过滤列
【发布时间】:2017-08-17 16:08:50
【问题描述】:

我在 R 中有两个 df(元=一些冗余信息)

df1:

                id  value1  value2  value3  value4
id1_meta_meta-meta  4.93    13.93   16.8    35.39
id2_meta_meta-meta  28.63   45.43   30.52   61.71
id3_meta_meta-meta  3.35    1.26    7.98    4.43
id4_meta_meta-meta  16.78   50.47   32.48   55.52
id5_meta_meta-meta  474.23  807.71  664.45  442.55
id6_meta_meta-meta  26.26   32.83   24.64   41.58
id7_meta_meta-meta  230.1   202.93  166.71  295.48
id8_meta_meta-meta  651.21  1282.71 1012.28 2650.21

df2:

V1
id1
id2
id3
id4
id5

问题

尝试根据 df2 中的 id 过滤 df1 中的行

代码

library(dplyr)
library(stringr)
df.common = df1 %>%
  filter(str_detect(id, '*_') %in% df2$V1)

错误

Error in filter_impl(.data, quo) : 
  Evaluation error: Syntax error in regexp pattern. (U_REGEX_RULE_SYNTAX).

期望的输出

df.common:

                id  value1  value2  value3  value4
id1_meta_meta-meta  4.93    13.93   16.8    35.39
id2_meta_meta-meta  28.63   45.43   30.52   61.71
id3_meta_meta-meta  3.35    1.26    7.98    4.43
id4_meta_meta-meta  16.78   50.47   32.48   55.52
id5_meta_meta-meta  474.23  807.71  664.45  442.55

【问题讨论】:

  • 如果您将filter 条件更改为filter(str_detect(id, df2$V1)),您的原始代码将起作用
  • @JakeKaupp 我收到此错误Warning message: In stri_detect_regex(string, pattern, opts_regex = opts(pattern)) : longer object length is not a multiple of shorter object length
  • 这是一个警告,而不是错误,会产生您想要的输出。
  • 是的,菜鸟的错误很抱歉,但我没有得到我所期望的> dim(df.common) [1] 2 13
  • str_detect 检测字符串并返回 TRUE 或 FALSE,因此您的代码在 df2 中寻找 TRUE 或 FALSE。相反,使用str_extract 拉出 ID 部分,然后用它进行测试:str_extract(id, "id[0-9]+") %in% df2$V1

标签: r dplyr stringr


【解决方案1】:

如果你使用dplyrstringr,也可以考虑这种方式。 str_replace_all 就像 gsubsemi_join 是一种“过滤连接”,允许您保留仅在 df2 中找到匹配的记录。

library(dplyr)
library(stringr)

df3 <- df1 %>%
  mutate(id2 = str_replace_all(id, "_.*", "")) %>%
  semi_join(df2, by = c("id2" = "V1")) %>%
  select(-id2)

df3
                  id value1 value2 value3 value4
1 id1_meta_meta-meta   4.93  13.93  16.80  35.39
2 id2_meta_meta-meta  28.63  45.43  30.52  61.71
3 id3_meta_meta-meta   3.35   1.26   7.98   4.43
4 id4_meta_meta-meta  16.78  50.47  32.48  55.52
5 id5_meta_meta-meta 474.23 807.71 664.45 442.55

【讨论】:

  • 我会试试这个,但如果我错了,请纠正我@PoGibas 的答案是简洁明了。
  • 嗯...如果你只想看最简洁的答案,我会尽快删除我的答案。如果您想了解更多关于 dplyrstringr 使用的信息,因为您正在使用这些软件包,我将在此处保留我的答案作为可选方法。你说什么?
  • 当然我已经接受了,你是正确的,它可以是可选的方式。
【解决方案2】:
  1. 使用gsub 修剪id 中的df1

    • gsub("_.*", "", df1$id) 将删除 _ 之后的所有内容
  2. 检查iddf2$V2 中的修剪内容(这将返回行号)

  3. df1中提取这些行

    df1[gsub("_.*", "", df1$id) %in% df2$V2, ]
    

【讨论】:

  • 它成功了,你能评论一下正在进行的事情将有助于学习吗,谢谢
  • 太棒了,欣赏!
  • @sbradbio 如果这是你想要的,那么你可以接受我的回答
  • 我现在不能,所以我会在 5 分钟后接受它,不知道为什么
猜你喜欢
  • 1970-01-01
  • 2019-11-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-25
  • 2018-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多