I am trying to pass unquoted arguments to plotly()
. If I call the column as-is (just the name), it works fine but if I try to pass the column name within a function like paste()
it fails. It also works with negative numbers but not positive ones. In dplyr
, I'd use curly-curly {{x}}
without a problem but plotly()
wants formulas to be passed so I'm a bit at a loss.
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'
CodePudding user response:
As @MrFlick said in a comment, the rlang
constructs used in tidyverse
won't necessarily work in non-tidyverse
packages. Here's a version of your function that does work, since it uses base methods to do the non-standard evaluation:
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
)
}
You want to evaluate the expressions passed as text
and at_y
in the context of the tibble mpg |> count(class)
, and that's something that is done by the two lines calling substitute
. This isn't identical to the rlang
evaluation, but it's close enough.