我正在尝试将未引用的参数传递给
plotly()
。如果我按原样调用该列(只是名称),它工作正常,但如果我尝试在像 paste()
这样的函数中传递列名,它会失败。它也适用于负数,但不适用于正数。在dplyr
中,我会毫无问题地使用卷曲的{{x}}
但是plotly()
想要通过公式所以我有点不知所措。
library(plotly)
library(tidyverse)
fn <- function(text, at_y) {
mpg |>
count(class) |>
plot_ly(x = ~class, y = ~n, type = "bar", color = I("grey")) |>
add_annotations(
text = enquo(text), # <---
y = enquo(at_y), # <---
showarrow = FALSE
)
}
# ok ----
fn(text = n, at_y = n)
fn(text = n, at_y = -1)
fn(text = -123, at_y = n)
# not ok ----
# positive integer
fn(text = n, at_y = 30)
#> Error in parent.env(x) : the empty environment has no parent
# used in a function
fn(text = paste("N=", n), at_y = n)
#> Error in paste("N=", n) :
#> cannot coerce type 'closure' to vector of type 'character'
正如@MrFlick 在评论中所说,
rlang
中使用的tidyverse
结构不一定适用于非tidyverse
包。这是您的函数的一个版本,因为它使用基本方法进行非标准评估:
fn <- function(text, at_y) {
data <- mpg |> count(class)
at_y <- eval(substitute(at_y), data)
text <- eval(substitute(text), data)
data |>
plot_ly(x = ~class, y = ~n, type = "bar", color = I("grey")) |>
add_annotations(
text = text, # <---
y = at_y, # <---
showarrow = FALSE
)
}
您想在小标题
text
的上下文中评估作为at_y
和mpg |> count(class)
传递的表达式,这是由调用substitute
的两行代码完成的。这与 rlang
评估不完全相同,但已经足够接近了。