需要解决的问题
我需要两个函数,在基于列指示器(即逻辑值)的数据框上实现和/或过滤器,这些指示器可能包含缺失值。函数的参数应该是要考虑的列的字符向量。
我的解决方案
filter_checked <- function(db, vars = NULL) {
db %>%
dplyr::filter(
dplyr::if_all(dplyr::all_of(vars), ~ !is.na(.x) & .x)
)
}
filter_or_checked <- function(db, vars = NULL) {
db %>%
dplyr::filter(
dplyr::if_any(dplyr::all_of(vars), ~ !is.na(.x) & .x)
)
}
示例测试通过
test_that("filter checks", {
foo <- tibble::tibble(
id = 1:5,
a = c(TRUE, TRUE, FALSE, FALSE, FALSE),
b = c(NA, TRUE, NA, TRUE, NA)
)
expect_equal(filter_checked(foo)[["id"]], 1:5)
expect_equal(filter_checked(foo, "a")[["id"]], 1:2)
expect_equal(filter_checked(foo, "b")[["id"]], c(2, 4))
expect_equal(filter_checked(foo, c("a", "b"))[["id"]], 2)
})
test_that("filter_or_checks", {
foo <- tibble::tibble(
id = 1:5,
a = c(TRUE, TRUE, FALSE, FALSE, FALSE),
b = c(NA, TRUE, NA, TRUE, NA)
)
expect_equal(filter_or_checked(foo)[["id"]], integer(0))
expect_equal(filter_or_checked(foo, "a")[["id"]], 1:2)
expect_equal(filter_or_checked(foo, "b")[["id"]], c(2, 4))
expect_equal(filter_or_checked(foo, c("a", "b"))[["id"]], c(1, 2, 4))
})
我的问题
我觉得我的函数非常复杂。不过,我认为这是我的知识不足。那么,是否有更好的(即更简单易读/理解/教授)tidyverse解决方案来解决这个问题呢?
filter_or_checked()
函数体中会变得非常复杂(而且有风险)。此外,mutate_at
目前已经被取代。 - Corrado