情节与DPLYR编程发生冲突?

发布于 2025-02-03 05:57:31 字数 2648 浏览 3 评论 0 原文

我正在重新编写产生图的函数,以便输出由 Plotly 驱动。

原始功能使用 dplyr编程样式。它在函数参数中具有数据变量,并且拥抱“通过以双重括号来包围该参数,例如滤波器(df,{var}})”。

到目前为止,预处理数据很好,结果可以用于创建图。 reprex 下面有效并产生了这个愚蠢的图。

foo <- function(data, var) {
  plot_data <- data |> 
    dplyr::summarise(min = min({{ var }}), max = max({{ var }}))
  plot_data
}

foo(mtcars, mpg)
#>    min  max
#> 1 10.4 33.9

plotly::plot_ly(data = foo(mtcars, mpg)) |>
  plotly::add_trace(
    x = ~min,
    y = ~max,
    type = "scatter",
    mode = "markers"
  )

“”

preprex package (v2.0.1)

现在,如果我想将图集成在函数中,我会在下面获得错误。

bar <- function(data, var) {
  
  plot_data <- data |> 
    dplyr::summarise(min = min({{ var }}), max = max({{ var }}))
  
  plotly::plot_ly(data = plot_data) |>
    plotly::add_trace(
      x = ~min,
      y = ~max,
      type = "scatter",
      mode = "markers"
    )
  
}

bar(mtcars, mpg)
#> Error in as.list.environment(x, all.names = TRUE): object 'mpg' not found

https://reprex.tidyverse.org”创建2022-05-31

plotly 与具有变量 var 仅应在数据环境中进行评估的变量,即使代码从未明确传递 var ,策划。 plotly 应仅知道 plot_data 传递给数据参数的,而expressions 〜min 〜max ,传递给 add_trace 函数的X和Y参数。但是,它仍然试图在功能环境中找到 mpg

似乎在 plotly 代码中,他们调用 as.list.environment(x,all.names = true),有效地评估了功能环境中的所有对象。但是我并不真正明白为什么这是以及如何规避它。

明确的解决方法可能是将变量名称作为字符向量传递,并使用.DATA代词来解决数据。

bar <- function(data, var) {
  
  plot_data <- data |> 
    dplyr::summarise(min = min(.data[[var]]), max = max(.data[[var]]))
  
  plotly::plot_ly(data = plot_data) |>
    plotly::add_trace(
      x = ~min,
      y = ~max,
      type = "scatter",
      mode = "markers"
    )
  
}

bar(mtcars, "mpg")

“”

preprex package (v2.0.1)

有效,我猜是因为角色向量可以始终在功能环境中成功评估。但是我真的很想像第一次尝试一样保持界面。

有什么想法如何处理?

I am re-writing a function that produces a plot, so that the output is powered by plotly.

The original function uses dplyr programming style. It has a data-variable in the function arguments and it embraces "the argument by surrounding it in doubled braces, like filter(df, {{ var }})".

So far so good, it works fine to pre-process the data and the result can be used to create the plot. reprex below works and produces this silly plot.

foo <- function(data, var) {
  plot_data <- data |> 
    dplyr::summarise(min = min({{ var }}), max = max({{ var }}))
  plot_data
}

foo(mtcars, mpg)
#>    min  max
#> 1 10.4 33.9

plotly::plot_ly(data = foo(mtcars, mpg)) |>
  plotly::add_trace(
    x = ~min,
    y = ~max,
    type = "scatter",
    mode = "markers"
  )

Created on 2022-05-31 by the reprex package (v2.0.1)

Now, if I want to integrate the plot in the function, I get the error below.

bar <- function(data, var) {
  
  plot_data <- data |> 
    dplyr::summarise(min = min({{ var }}), max = max({{ var }}))
  
  plotly::plot_ly(data = plot_data) |>
    plotly::add_trace(
      x = ~min,
      y = ~max,
      type = "scatter",
      mode = "markers"
    )
  
}

bar(mtcars, mpg)
#> Error in as.list.environment(x, all.names = TRUE): object 'mpg' not found

Created on 2022-05-31 by the reprex package (v2.0.1)

It's like plotly does not get along with having a variable var that should only be evaluated within the data environment, even though the code never explicitly passes var to plotly. plotly should only be aware of plot_data passed to the data argument, and the expressions ~min and ~max, passed to the x and y arguments of the add_trace function. But still, it tries to find mpg in the function environment.

It seems somewhere in the plotly code they call as.list.environment(x, all.names = TRUE), effectively evaluating all objects in the function environment. But I do not really get why is this and how to circumvent it.

A clear workaround could be to pass the variable name as a character vector and use the .data pronoun for wrangling the data.

bar <- function(data, var) {
  
  plot_data <- data |> 
    dplyr::summarise(min = min(.data[[var]]), max = max(.data[[var]]))
  
  plotly::plot_ly(data = plot_data) |>
    plotly::add_trace(
      x = ~min,
      y = ~max,
      type = "scatter",
      mode = "markers"
    )
  
}

bar(mtcars, "mpg")

Created on 2022-05-31 by the reprex package (v2.0.1)

That works, I guess because the character vector can always be successfully evaluated in the function environment. But I would really like to keep the interface as in the first attempt.

Any ideas how to deal with this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文