我正在重新编写产生图的函数,以便输出由 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?
发布评论