根据 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 列上过滤。
是否有任何替代函数或包可以用来解决我的问题?
非常感谢任何帮助!
我们可以使用 filter
和 across
。我们使用 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')), ]
我想使用 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 列上过滤。
是否有任何替代函数或包可以用来解决我的问题? 非常感谢任何帮助!
我们可以使用 filter
和 across
。我们使用 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')), ]