将 any()、all() 等与 dplyr::filter() + dplyr::across() 组合一起使用的正确方法是什么?

问题描述

假设我有以下 data.frame df

#         col1        col2       col3 othercol1 othercol11
# 1      Hello WHAT_hello2      Hello        10          3
# 2 WHAT_hello  WHAT_hello WHAT_hello         1          2
# 3      Hello       Hello      Hello         9          1

我想处理 data.frame 以仅保留那些在 WHAT_col1 或 {{1} 中的至少一个中包含前缀 col2 的行}.

现在我知道我可以用 col3 轻松做到这一点,但我试图使用 |dplyr::across 以及 tidyselect::matches 和 {{1} } 将 base::any 指向右列。但这似乎不起作用,即使与 stringr::str_detect 结合使用也是如此。

那么这里的正确方法是什么?我做错了什么?

我想使用 dplyr::filter + dplyr::rowwise 主要是因为我可能不一定事先知道我在实际数据集中有多少这样的列。

以下是我的示例(数据 + 代码):

across

解决方法

对于应用于行而不是列的函数,您可以将 c_acrossrowwise 结合使用:

df %>% 
  rowwise() %>% 
  filter(any(str_detect(c_across(matches('^col')),'^WHAT')))

# # A tibble: 2 x 5
# # Rowwise: 
#   col1       col2        col3       othercol1 othercol11
#   <chr>      <chr>       <chr>          <int>      <int>
# 1 Hello      WHAT_hello2 Hello              9          7
# 2 WHAT_hello WHAT_hello  WHAT_hello         3         10

或者,将 acrossrowSums 一起使用:

row_lgl <- 
  df %>% 
    transmute(across(.cols = matches("^col"),.fns = ~ str_detect(.x,"^WHAT"))) %>% 
    rowSums %>% 
    '>'(0)
           
df %>% 
  filter(row_lgl)
#         col1        col2       col3 othercol1 othercol11
# 1      Hello WHAT_hello2      Hello         9          7
# 2 WHAT_hello  WHAT_hello WHAT_hello         3         10
,

使用base

df <- data.frame(col1 = c("Hello","WHAT_hello","Hello"),col2 = c("WHAT_hello2",col3 = c("Hello",othercol1 = sample(1:10,3),othercol11 = sample(1:10,stringsAsFactors = FALSE)

df 
#>         col1        col2       col3 othercol1 othercol11
#> 1      Hello WHAT_hello2      Hello         1          9
#> 2 WHAT_hello  WHAT_hello WHAT_hello         3          2
#> 3      Hello       Hello      Hello         4          8

df[apply(df,1,function(x) sum(grepl(pattern = "^WHAT_",x = x))) != 0,]
#>         col1        col2       col3 othercol1 othercol11
#> 1      Hello WHAT_hello2      Hello         1          9
#> 2 WHAT_hello  WHAT_hello WHAT_hello         3          2

reprex package (v0.3.0) 于 2021 年 1 月 20 日创建

使用tidyverse

library(tidyverse)
df <- data.frame(col1 = c("Hello",stringsAsFactors = FALSE)


df %>% 
  filter(rowSums(across(.cols = where(is.character),"^WHAT"))) != 0)
#>         col1        col2       col3 othercol1 othercol11
#> 1      Hello WHAT_hello2      Hello         1          3
#> 2 WHAT_hello  WHAT_hello WHAT_hello         7          4

reprex package (v0.3.0) 于 2021 年 1 月 20 日创建

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...