可以关注多列时过滤行

filter row when multiple columns can be concerned

我有这个数据:

# A tibble: 20 x 6
      ID style param1 param2 param3 param4
   <dbl> <chr> <chr>  <chr>  <chr>  <chr> 
 1     1 ar    R78    NA     NA     NA    
 2     2 bg    NA     NA     NA     NA    
 3     3 bh    NA     NA     NA     NA    
 4     4 ar    NA     R78    NA     NA    
 5     5 bg    NA     NA     NA     NA    
 6     6 bh    NA     NA     NA     NA    
 7     7 ar    R78    NA     NA     NA    
 8     8 bg    NA     NA     R78    NA    
 9     9 bh    NA     NA     NA     NA    
10    10 ar    NA     R78    NA     NA    
11    11 bg    NA     NA     NA     NA    
12    12 bh    NA     NA     R78    NA    
13    13 ar    NA     NA     NA     NA    
14    14 bg    R78    NA     NA     NA    
15    15 bh    NA     NA     NA     NA    
16    16 ar    NA     NA     NA     NA    
17    17 bg    NA     NA     NA     NA    
18    18 bh    R78    NA     NA     NA    
19    19 ar    NA     NA     NA     R78   
20    20 bg    NA     NA     NA     NA 

当 R78 在列 param1、param2、param3 或 param4

中时,我想使用 dplyr::filter 到 select 行

我试试:

data %>%
  filter(across(param1:param4) == "R78")

哪个 return 是我:

# A tibble: 4 x 6
     ID style param1 param2 param3 param4
  <dbl> <chr> <chr>  <chr>  <chr>  <chr> 
1     1 ar    R78    NA     NA     NA    
2     7 ar    R78    NA     NA     NA    
3    14 bg    R78    NA     NA     NA    
4    18 bh    R78    NA     NA     NA  

这和我做的一样data %>% filter(param1 == "R78")

...

也许我误用了 "across" 函数。我试过多个“|”但从不工作:/

我对我的代码的期望是它必须 return 我对第 1、4、7、10、12、14 行感兴趣;仅限 18 岁和 19 岁:/

谢谢你!

across 按列工作。在这种情况下,我认为最好使用 filter_at :

library(dplyr)
df %>% filter_at(vars(param1:param4), any_vars(. == 'R78'))

#   ID style param1 param2 param3 param4
#1   1    ar    R78   <NA>   <NA>   <NA>
#4   4    ar   <NA>    R78   <NA>   <NA>
#7   7    ar    R78   <NA>   <NA>   <NA>
#8   8    bg   <NA>   <NA>    R78   <NA>
#10 10    ar   <NA>    R78   <NA>   <NA>
#12 12    bh   <NA>   <NA>    R78   <NA>
#14 14    bg    R78   <NA>   <NA>   <NA>
#18 18    bh    R78   <NA>   <NA>   <NA>
#19 19    ar   <NA>   <NA>   <NA>    R78

使 across 工作的一个技巧是使用 Reduce :

df %>% filter(Reduce(`|`, across(param1:param4, ~. == 'R78')))

在基础 R 中,您可以使用 rowSums :

cols <- paste0('param', 1:4)
df[rowSums(df[cols] == 'R78', na.rm = TRUE) > 0, ]

当然有老式的简单但冗长的解决方案,即只表达所有 "ors"。

mydf %>% filter(param1 == "R78" | param2 == "R78" | param3 == "R78" | param4 == "R78" )

这里只是我的两分钱:这是另一种可能的解决方案,在谈论 filter 功能时遵循 dplyr documentation 上的指示。它说:

Previously, filter() was paired with the all_vars() and any_vars() helpers. Now, across() is equivalent to all_vars(), and there’s no direct replacement for any_vars(). However you can make a simple helper yourself.

在这里,我创建了辅助函数 rowAny,其中 returns 一个逻辑向量,据此判断条件 x == "R78" 是否满足,然后我将它应用到 across.

rowAny <- function(x) {rowSums(x == "R78", na.rm = TRUE) > 0}
df %>% filter(rowAny(across(param1:param4)))

# A tibble: 9 x 6
#      ID style param1 param2 param3 param4
#   <int> <chr> <chr>  <chr>  <chr>  <chr> 
# 1     1 ar    R78    NA     NA     NA    
# 2     4 ar    NA     R78    NA     NA    
# 3     7 ar    R78    NA     NA     NA    
# 4     8 bg    NA     NA     R78    NA    
# 5    10 ar    NA     R78    NA     NA    
# 6    12 bh    NA     NA     R78    NA    
# 7    14 bg    R78    NA     NA     NA    
# 8    18 bh    R78    NA     NA     NA    
# 9    19 ar    NA     NA     NA     R78