dplyr滤波器中的非标准评估(NSE)&从MySQL中提取数据

时间:2014-10-21 17:04:52

标签: r lazy-evaluation dplyr

我想通过动态过滤器从sql server中提取一些数据。我以下列方式使用了伟大的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

这段代码工作正常,但现在我想以某种方式将其循环到我的表的所有列上,因此我想将过滤器编写为:

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

然后使用更新的过滤器重新应用第一个代码。

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

虽然第一个工作代码生成了以下形式的查询:

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

(`登录列名),第二个生成表单的查询:

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

(&#39;在列名中签名)

有没有人对如何制定过滤条件以使其有效有任何建议?

3 个答案:

答案 0 :(得分:43)

它与SQL无关。 R中的这个例子也不起作用:

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

它不起作用,因为您需要传递filter_表达式~ v1 == 1 - 而不是表达式~ "v1" == 1

要解决此问题,只需使用引用运算符quo和dequoting运算符!!

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

答案 1 :(得分:8)

另一种解决方案,dplyr版本0.5.0(可能早于此实现),可以将组合字符串作为.dots参数传递,我发现它比lazyeval :: interp解决方案更具可读性:

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及更高版本的

UPDATE

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是一个字符串变量。)

第二次更新:Edwin Thoen为整洁的评估创建了一个很好的备忘单:https://edwinth.github.io/blog/dplyr-recipes/

答案 2 :(得分:5)

这是一个稍微简洁的解决方案,它使用提取函数var winHeight = $(window).height(); //image popup on hover $(".imageZoom").hover(function() { $(this).parent().append("<div class='bigImage'><img src='"+ $(this).attr("href") +"'></div>"); $(".bigImage").css("width", "50vw").css("max-width", "800").css("position", "absolute").css("display", "none"); var imageHeight = $(".bigImage").height(); var top = $(window).scrollTop(); var imageTop = top; if(imageHeight < winHeight) { imageTop += Math.ceil((winHeight - imageHeight) / 2); } $(".bigImage").css("top", imageTop).css("margin-left", 100).show(600); }, function() { $(this).parent().find("div").remove(); }); 的典型行为来逐字符选择值而不是将其转换为语言元素:

'['