Home > Mobile >  r - passing unquoted variables to plotly formula
r - passing unquoted variables to plotly formula

Time:12-01

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.

  • Related