dplyr的filter_中的非标准评估(NSE)和从MySQL中提取数据

我想从一个dynamicfilter的SQL服务器拉一些数据。 我用以下方式使用伟大的R包dplyr:

#Create the filter filter_criteria = ~ column1 %in% some_vector #Connect to the database connection <- src_mysql(dbname <- "mydbname", user <- "myusername", password <- "mypwd", host <- "myhost") #Get data data <- connection %>% tbl("mytable") %>% #Specify which table filter_(.dots = filter_criteria) %>% #non standard evaluation filter collect() #Pull data 

这段代码工作正常,但现在我想循环它在我的表的所有列,所以我想写的filter为:

 #Dynamic filter i <- 2 #With a loop on this i for instance which_column <- paste0("column",i) filter_criteria <- ~ which_column %in% some_vector 

然后用更新的filter重新应用第一个代码。

不幸的是,这种方法没有给出预期的结果。 事实上,它不会给出任何错误,但甚至不会将任何结果拉入R.特别是,我查看了两段代码生成的SQL查询,有一个重要的区别。

第一个工作代码生成一个表单查询:

 SELECT ... FROM ... WHERE `column1` IN .... 

(`login列名称),第二个生成一个查询的forms:

 SELECT ... FROM ... WHERE 'column1' IN .... 

('login列名称)

有没有人有任何build议如何制定过滤条件,使其工作?

这不是真的与SQL有关。 R中的这个例子也不起作用:

 df <- data.frame( v1 = sample(5, 10, replace = TRUE), v2 = sample(5,10, replace = TRUE) ) df %>% filter_(~ "v1" == 1) 

它不起作用,因为你需要传递filter_expression式filter_ ~ v1 == 1 – 而不是expression式~ "v1" == 1

dplyr版本> = 0.6

要解决这个问题,只需使用引号操作符和引号操作符!!

 library(dplyr) which_column = quot(v1) df %>% filter(!!which_column == 1) 

dplyr版本<0.6

为了解决这个问题,使用lazyeval包中的函数interp。

 library(lazyeval) filter_criteria <- interp(~ which_column == 1, which_column = as.name("v1")) df %>% filter_(filter_criteria) 

下面是一个稍微不详细的解决scheme,其中一个使用了提取函数的典型行为: '['在按字符值select列而不是将其转换为语言元素:

 df %>% filter(., '['(., which_column)==1 ) set.seed(123) df <- data.frame( v1 = sample(5, 10, replace = TRUE), v2 = sample(5,10, replace = TRUE) ) which_column <- "v1" df %>% filter(., '['(., which_column)==1) # v1 v2 #1 1 5 

另一种解决方法是,使用dplyr版本0.5.0(可能早于实现),可以传递一个组合的string作为.dots参数,我发现它比lazyeval :: interp解决scheme更具可读性:

 df <- data.frame( v1 = sample(5, 10, replace = TRUE), v2 = sample(5,10, replace = TRUE) ) which_col <- "v1" which_val <- 1 df %>% filter_(.dots= paste0(which_col, "== ", which_val)) v1 v2 1 1 1 2 1 2 3 1 4 

更新 dplyr 0.6:

 packageVersion("dplyr") # [1] '0.5.0.9004' df %>% filter(UQ(rlang::sym(which_col))==which_val) #OR df %>% filter((!!rlang::sym(which_col))==which_val) 

(类似于@Matthew对dplyr 0.6的回应,但我认为which_col是一个stringvariables。)