对多个 dplyr 过滤条件使用 tidy eval
Using tidy eval for multiple dplyr filter conditions
我不熟悉 tidy eval 并尝试编写通用函数 - 我现在正在努力解决的一件事是为分类变量编写多个过滤条件。这就是我现在正在使用的-
create_expr <- function(name, val){
if(!is.null(val))
val <- paste0("c('", paste0(val, collapse = "','"), "')")
paste(name, "%in%", val)
}
my_filter <- function(df, cols, conds){
# Args:
# df: dataframe which is to be filtered
# cols: list of column names which are to be filtered
# conds: corresponding values for each column which need to be filtered
cols <- as.list(cols)
conds <- as.list(conds)
args <- mapply(create_expr, cols, conds, SIMPLIFY = F)
if(!length(args))
stop(cat("No filters provided"))
df <- df %>% filter_(paste(unlist(args), collapse = " & "))
return(df)
}
my_filter(gapminder, cols = list("continent", "country"),
conds = list("Europe", c("Albania", "France")))
我想知道如何使用整洁的评估实践重写它。我发现 material 对多个参数使用 quos() 但如您所见,我这里有两个不同的参数列表,它们需要相互映射。
感谢任何帮助,谢谢!
使用 tidyverse,您可以 re-write 发挥
的作用
library(dplyr)
library(purrr) # for map2()
my_filter <- function(df, cols, conds){
fp <- map2(cols, conds, function(x, y) quo((!!(as.name(x))) %in% !!y))
filter(df, !!!fp)
}
my_filter(gapminder::gapminder, cols = list("continent", "country"),
conds = list("Europe", c("Albania", "France")))
这相当于调用
filter(gapminder, continent %in% "Europe", country %in% c("Albania", "France"))
这样做的主要原因是您可以将多个参数传递给 filter()
,并且它们与 &
隐式组合。 map2()
只是 mapply
的 tidyverse 等价物,有两个要迭代的对象。
我不熟悉 tidy eval 并尝试编写通用函数 - 我现在正在努力解决的一件事是为分类变量编写多个过滤条件。这就是我现在正在使用的-
create_expr <- function(name, val){
if(!is.null(val))
val <- paste0("c('", paste0(val, collapse = "','"), "')")
paste(name, "%in%", val)
}
my_filter <- function(df, cols, conds){
# Args:
# df: dataframe which is to be filtered
# cols: list of column names which are to be filtered
# conds: corresponding values for each column which need to be filtered
cols <- as.list(cols)
conds <- as.list(conds)
args <- mapply(create_expr, cols, conds, SIMPLIFY = F)
if(!length(args))
stop(cat("No filters provided"))
df <- df %>% filter_(paste(unlist(args), collapse = " & "))
return(df)
}
my_filter(gapminder, cols = list("continent", "country"),
conds = list("Europe", c("Albania", "France")))
我想知道如何使用整洁的评估实践重写它。我发现 material 对多个参数使用 quos() 但如您所见,我这里有两个不同的参数列表,它们需要相互映射。
感谢任何帮助,谢谢!
使用 tidyverse,您可以 re-write 发挥
的作用library(dplyr)
library(purrr) # for map2()
my_filter <- function(df, cols, conds){
fp <- map2(cols, conds, function(x, y) quo((!!(as.name(x))) %in% !!y))
filter(df, !!!fp)
}
my_filter(gapminder::gapminder, cols = list("continent", "country"),
conds = list("Europe", c("Albania", "France")))
这相当于调用
filter(gapminder, continent %in% "Europe", country %in% c("Albania", "France"))
这样做的主要原因是您可以将多个参数传递给 filter()
,并且它们与 &
隐式组合。 map2()
只是 mapply
的 tidyverse 等价物,有两个要迭代的对象。