根据 2 个不同的条件过滤多个字符串列 - 关于 "grepl" 和 "starts_with" 的问题

Filtering multiple string columns based on 2 different criteria - questions about "grepl" and "starts_with"

我想使用 select 和 dplyr 的过滤函数创建我的数据子集。我咨询了几个关于partial string matches and 的类似问题,但没有找到解决我的问题的方法。

我要过滤的列都以相同的字母开头,比方说“DGN”。所以我有 DGN1、DGN2、DGN3 等,一直到 DGN25。我要过滤的两个条件是 contains "C18"starts with "153".

理想情况下,我想要 运行 一个如下所示的代码块:

dgn_subset <- df %>%
    select(ID, date, starts_with("DGN") %>%
    filter(grepl("C18"|starts_with("153"), starts_with("DGN")))

这里有两个主要问题 -- 我认为 grepl 不能将“starts_with”作为模式的输入。此外,它不能将“starts_with”作为列参数(我认为它可能一次只能过滤一列?)。

为了使代码正常工作,我可以将 starts_with("153") 部分替换为“153”,将 starts_with("DGN") 部分带有“DGN1”,但这给了我很多我不想要的观察结果,它只在第一个 DGN 列上过滤。

是否有任何替代函数或包可以用来解决我的问题? 非常感谢任何帮助!

我们可以使用 filteracross。我们使用 c_across 循环遍历列,指定 select_helpers (starts_with) 中的列名称匹配,得到逻辑输出 grepl 检查“C18”或 (|) 以(^) 153

开头的数字
library(dplyr) #1.0.0
library(stringr)
df %>%
    # // do a row wise grouping
    rowwise() %>%
    # // subset the columns that starts with 'DGN' within c_across
    # // apply grepl condition on the subset
    # // wrap with any for any column in a row meeting the condition
    filter(any(grepl("C18|^153", c_across(starts_with("DGN")))))

filter_at

df %>% 
  # //apply the any_vars along with grepl in filter_at
  filter_at(vars(starts_with("DGN")), any_vars(grepl("C18|^153", .)))

数据

df <-  data.frame(ID = 1:3, DGN1 = c("2_C18", 32, "1532"), 
          DGN2 = c("24", "C18_2", "23"))

在 base R 中,您可以使用 startsWith 到 select 您想要查找的列,使用 sapply 检查这些列中的模式。使用 rowSums 计算该模式在每一行中出现的次数,然后 select 计算至少出现一次的行。

cols <- startsWith(names(df), 'DGN')
df[rowSums(sapply(df[cols], grepl, pattern = 'C18|^153')) > 0, ]

类似的逻辑,但使用 lapply 你可以这样做:

df[Reduce(`|`, lapply(df[cols], grepl, pattern = 'C18|^153')), ]