dplyr 用多个条件过滤多个变量(列)
dplyr filter multiple variables (columns) with multiple conditions
我打算用一行中的多列过滤多列数据,以减少 运行ning 代码所用的时间。这是我用来测试我的代码的示例数据。基本上,我想删除包含 0、1、2 和 NA 的所有行。
test <- data.frame(A = c(1,0,2,3,4,0,5,6,0,7,0,8,0,9,NA),
B = c(0,1,0,2,3,4,0,5,0,7,8,0,NA,9,0),
C = c(1,2,3,0,0,4,5,6,0,7,0,8,NA,0,9))
我使用以下代码来清理我的数据。虽然它完成了工作,但代码非常乏味,当我 运行 使用大型数据库时需要花费我很多时间。
test %>% filter(!is.na(A)) %>%
filter(!is.na(B)) %>%
filter(!is.na(C)) %>%
filter(A != 0) %>%
filter(A != 1) %>%
filter(A != 2) %>%
filter(B != 0) %>%
filter(B != 1) %>%
filter(B != 2) %>%
filter(C != 0) %>%
filter(C != 1) %>%
filter(C != 2)
A B C
1 6 5 6
2 7 7 7
我尝试使用 filter
、filter_at
和 any_vars
来缩短代码,但没有成功。下面是我尝试处理这个问题(所有这些代码都不起作用,因为它们无法删除包含 0(或 1,2 和 NA)的行。
df_total <- test %>%
filter_at(vars(A, B, C), any_vars(!is.na(.))) %>%
filter_at(vars(A, B, C), any_vars(. != 2)) %>%
filter_at(vars(A, B, C), any_vars(. != 1)) %>%
filter_at(vars(A, B, C), any_vars(. != 0))
df_total <- test %>%
filter_at(vars(A, B, C), any_vars(!is.na(.) | . != 2 | . != 1 | . != 0))
df_total <- test %>%
filter(!is.na(A) | A!= 2 | A!= 1 | A!= 0) %>%
filter(!is.na(B) | B!= 2 | B!= 1 | B!= 0) %>%
filter(!is.na(C) | C!= 2 | C!= 1 | C!= 0) %>%
我想不通我在这里做错了什么。为了解决这个问题,我在文档和R之间来回奔波,但我的努力没有用。您能否向我建议我在代码中做错了什么?如何在一行中编写具有多个条件的多列代码?一行的目的是加快 R 的 运行ning 时间。任何有助于找到答案的意见/建议/资源都将不胜感激!谢谢。
test %>%
filter(across(c(A, B, C), function(x) !is.na(x) & !x %in% c(0, 1, 2)))
# A B C
# 6 5 6
# 7 7 7
另一个可能的解决方案:
library(dplyr)
test %>%
filter(complete.cases(.) & if_all(everything(), ~ !(.x %in% 0:2)))
#> A B C
#> 1 6 5 6
#> 2 7 7 7
我打算用一行中的多列过滤多列数据,以减少 运行ning 代码所用的时间。这是我用来测试我的代码的示例数据。基本上,我想删除包含 0、1、2 和 NA 的所有行。
test <- data.frame(A = c(1,0,2,3,4,0,5,6,0,7,0,8,0,9,NA),
B = c(0,1,0,2,3,4,0,5,0,7,8,0,NA,9,0),
C = c(1,2,3,0,0,4,5,6,0,7,0,8,NA,0,9))
我使用以下代码来清理我的数据。虽然它完成了工作,但代码非常乏味,当我 运行 使用大型数据库时需要花费我很多时间。
test %>% filter(!is.na(A)) %>%
filter(!is.na(B)) %>%
filter(!is.na(C)) %>%
filter(A != 0) %>%
filter(A != 1) %>%
filter(A != 2) %>%
filter(B != 0) %>%
filter(B != 1) %>%
filter(B != 2) %>%
filter(C != 0) %>%
filter(C != 1) %>%
filter(C != 2)
A B C
1 6 5 6
2 7 7 7
我尝试使用 filter
、filter_at
和 any_vars
来缩短代码,但没有成功。下面是我尝试处理这个问题(所有这些代码都不起作用,因为它们无法删除包含 0(或 1,2 和 NA)的行。
df_total <- test %>%
filter_at(vars(A, B, C), any_vars(!is.na(.))) %>%
filter_at(vars(A, B, C), any_vars(. != 2)) %>%
filter_at(vars(A, B, C), any_vars(. != 1)) %>%
filter_at(vars(A, B, C), any_vars(. != 0))
df_total <- test %>%
filter_at(vars(A, B, C), any_vars(!is.na(.) | . != 2 | . != 1 | . != 0))
df_total <- test %>%
filter(!is.na(A) | A!= 2 | A!= 1 | A!= 0) %>%
filter(!is.na(B) | B!= 2 | B!= 1 | B!= 0) %>%
filter(!is.na(C) | C!= 2 | C!= 1 | C!= 0) %>%
我想不通我在这里做错了什么。为了解决这个问题,我在文档和R之间来回奔波,但我的努力没有用。您能否向我建议我在代码中做错了什么?如何在一行中编写具有多个条件的多列代码?一行的目的是加快 R 的 运行ning 时间。任何有助于找到答案的意见/建议/资源都将不胜感激!谢谢。
test %>%
filter(across(c(A, B, C), function(x) !is.na(x) & !x %in% c(0, 1, 2)))
# A B C
# 6 5 6
# 7 7 7
另一个可能的解决方案:
library(dplyr)
test %>%
filter(complete.cases(.) & if_all(everything(), ~ !(.x %in% 0:2)))
#> A B C
#> 1 6 5 6
#> 2 7 7 7