结合公式和整洁的评估(情节) [英] combine formula and tidy eval (plotly)

查看:62
本文介绍了结合公式和整洁的评估(情节)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难理解这一点.

下面让我以整洁"的方式过滤我的 data.frame,并使用 plotly 绘制一个图.在这种情况下,我使用 plotly 的基于公式的 API 来说明要使用数据框的哪些列:

图书馆(情节)tidy_filter = 函数(数据,x){x = enquo(x)过滤器(数据,!!x > 5)}mtcars %>%tidy_filter(wt) %>%plot_ly(x = ~wt, y = ~wt)

我可以将其包装在一个函数中以获得相同的结果:

tidy_ply = function(data, x) {x = enquo(x)数据 = 过滤器(数据,!!x > 5)plot_ly(数据,x = x,y = x)}tidy_ply(mtcars,重量)

现在:

  1. 我假设在这种情况下 enquo(x) 至少部分等效于 ~wt 因为它似乎是这样工作的.但它们是两种不同的东西(quosure VS 公式).它们之间的关系是什么,为什么上面会起作用?

  2. plotly 的公式 API 的优点是,如果我想操作输入值,我可以做~wt/2 之类的事情.但是在上面,执行 plot_ly(data, x = x, y = x/2) 会产生错误.有没有办法让这个工作?

我想普遍的问题是如何最好地将 tidy eval 方法与 plotly 的公式方法结合起来?

解决方案

从此 (v0.2.1.9000) 于 2019 年 4 月 3 日创建

I'm struggling to understand this.

The below lets me filter my data.frame in a "tidy" way, and draw a plot using plotly. In this case, I'm using plotly's formula-based API to say which columns of a data frame to use:

library(plotly)

tidy_filter = function(data, x) {
  x = enquo(x)
  filter(data, !!x > 5)
}

mtcars %>% 
  tidy_filter(wt) %>% 
  plot_ly(x = ~wt, y = ~wt)

I can wrap this in a single function to get the same result:

tidy_ply = function(data, x) {
  x = enquo(x)
  data = filter(data, !!x > 5)
  plot_ly(data, x = x, y = x)
}

tidy_ply(mtcars, wt)

Now:

  1. I assume that enquo(x) in this case is at least in part equivalent to ~wt since that's how it seems to work. But they are two different things (quosure VS formula). What is the relationship between them, and why does the above work?

  2. The advantage of plotly's formula API is that if I want to manipulate the input value, I can do things like ~wt/2. But in the above, doing plot_ly(data, x = x, y = x/2) produces an error. Is there a way to make this work?

I guess the general question is how to best combine the tidy eval approach with plotly's formula approach?

解决方案

From this answer by @alistaire:

The plotly R package was created a little before rlang, and has its own non-standard evaluation (NSE) system, that as far as I can tell is mostly only documented in the examples.

When NSE systems go sideways, the quickest way to get it to work is to rewrite all the code dynamically and then evaluate it. Here, wrap the whole plotly pipeline in quo with !! substitution wherever you like, then call quo_squash on it to collapse it to a single expression (instead of nested quosures), and then call eval_tidy on the whole lot to actually run it.

In plotly, ~ is used to refer to a column in the dataset to be visualized (@cpsievert).

In your example, x is a quosure thus you have to first unquote it before applying any base operator. That's what the error message told you:

Error: Base operators are not defined for quosures.
Do you need to unquote the quosure?

  # Bad:
  myquosure / rhs

  # Good:
  !!myquosure / rhs

Here is a working solution:

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)
#> 

Created on 2019-04-03 by the reprex package (v0.2.1.9000)

这篇关于结合公式和整洁的评估(情节)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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