我正在努力理解这一点。
下面的内容使我可以“整洁”地过滤data.frame,并使用plotly绘制图。在这种情况下,我使用plotly基于公式的API来说明要使用数据框的哪些列:
library(plotly)
tidy_filter = function(data, x) {
x = enquo(x)
filter(data, !!x > 5)
}
mtcars %>%
tidy_filter(wt) %>%
plot_ly(x = ~wt, y = ~wt)
我可以将其包装在单个函数中以获得相同的结果:
tidy_ply = function(data, x) {
x = enquo(x)
data = filter(data, !!x > 5)
plot_ly(data, x = x, y = x)
}
tidy_ply(mtcars, wt)
现在:
我假设在这种情况下,enquo(x)
至少部分等效于~wt
,因为这似乎是这样工作的。但是它们是两个不同的东西(Quosure VS公式)。它们之间是什么关系,为什么上述方法有效?
plotly的公式API的优势在于,如果我要操纵输入值,可以执行类似~wt/2
的操作。但是在上面,执行plot_ly(data, x = x, y = x/2)
会产生错误。有办法使这项工作吗?
我想普遍的问题是如何最好地将整洁的评估方法与plotly的公式方法结合起来?
答案 0 :(得分:2)
来自@alistaire的answer:
plotly
R软件包是在rlang
之前创建的,它具有自己的非标准评估(NSE)系统,据我所知,大部分仅在示例中进行了说明。当NSE系统横盘整理时,使其正常工作的最快方法是动态重写所有代码,然后对其进行评估。在这里,将整个
plotly
管道包装在quo
中,并在任意位置使用!!
替换,然后在其上调用quo_squash
将其折叠为单个表达式(而不是嵌套的quoures) ,然后整个调用eval_tidy
来实际运行它。在
plotly
中,~
用于引用数据集中要可视化的列(@cpsievert)。
在您的示例中,x
是一种保证,因此您必须在应用任何基本运算符之前先取消报价。这就是错误消息告诉您的内容:
Error: Base operators are not defined for quosures.
Do you need to unquote the quosure?
# Bad:
myquosure / rhs
# Good:
!!myquosure / rhs
这是一个可行的解决方案:
library(rlang)
library(plotly)
tidy_ply2 <- function(data, x) {
x = enquo(x)
print(x)
data = filter(data, !!x > 5)
# https://rlang.r-lib.org/reference/quasiquotation.html
cat('\nUse qq_show() to debug the effect of unquoting operators\n')
qq_show(plot_ly(data, x = ~!!x, y = ~!!x/2))
# `base::eval` works too
eval_tidy(
quo_squash(
quo({
plot_ly(data, x = ~!!x, y = ~!!x/2)
})
)
)
}
tidy_ply2(mtcars, wt)
#> <quosure>
#> expr: ^wt
#> env: global
#>
#> Use qq_show() to debug the effect of unquoting operators
#> plot_ly(data, x = ~^wt, y = ~(^wt) / 2)
#>
由reprex package(v0.2.1.9000)于2019-04-03创建