对多个dplyr过滤条件使用整洁的评估 [英] Using tidy eval for multiple dplyr filter conditions

查看:166
本文介绍了对多个dplyr过滤条件使用整洁的评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是不熟悉eval并尝试编写泛型函数的新手-我现在正努力解决的一件事是为分类变量编写多个过滤条件.这就是我现在正在使用的-

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. 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")))

我想知道如何使用整洁的评估实践将其重写.我已经找到了关于对多个参数使用quos()的资料,但是正如您所看到的,我在这里有两个不同的参数列表,这些列表需要相互映射.

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.

感谢您的帮助,谢谢!

推荐答案

使用tidyverse,您可以将该函数重写为

Using the tidyverse, you could re-write that function as

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的最上等式,具有两个要迭代的对象.

The main reason this works is that you can pass multiple arguments to filter() and they are implicitly combined with &. And map2() is just a tidyverse equivalent for mapply with two objects to iterate.

这篇关于对多个dplyr过滤条件使用整洁的评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆