可以关注多列时过滤行
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
我有这个数据:
# 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 theall_vars()
andany_vars()
helpers. Now,across()
is equivalent toall_vars()
, and there’s no direct replacement forany_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