[英]Using tidy eval for multiple dplyr filter conditions
I'm new to tidy eval and trying to write generic functions- one thing I'm struggling with right now is writing multiple filter conditions for categorical variables. 我是不熟悉eval并尝试编写通用函数的新手-我现在正努力解决的一件事是为分类变量编写多个过滤条件。 This is what I'm using right now-
这就是我现在正在使用的
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")))
I want to know how this could be re-written using tidy eval practices. 我想知道如何使用整洁的评估实践将其重写。 I've found material on using quos() for multiple arguments but as you can see I have two different lists of arguments here which need to be mapped to each other.
我已经找到了关于对多个参数使用quos()的资料,但是如您所见,这里有两个不同的参数列表,它们需要相互映射。
Any help is appreciated, Thanks! 任何帮助表示赞赏,谢谢!
Using the tidyverse, you could re-write that function as 使用tidyverse,您可以将该函数重写为
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")))
This is calling the equivalent of 这相当于
filter(gapminder, continent %in% "Europe", country %in% c("Albania", "France"))
The main reason this works is that you can pass multiple arguments to filter()
and they are implicitly combined with &
. 起作用的主要原因是您可以将多个参数传递给
filter()
并且它们与&
隐式组合。 And map2()
is just a tidyverse equivalent for mapply
with two objects to iterate. 和
map2()
仅仅是一个tidyverse等效mapply
有两个对象进行迭代。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.