I'm hoping to lure somebody who knows more than i do about rlang into helping me understand it better. I have a weird workaround for programming around leaflet, but I'd like to better understand 1) why this works, 2) why the traditional inline !!
doesn't work, and 3) how I can debug quosure errors on my own without coming up with weird hacks. I'm not sure whether this is an rlang question, a leaflet question, a combination of the two, or something else entirely.
Whenever I've tried to program around a leaflet object (e.g., by creating a function that takes a column in a dataframe as an argument, and maps that to some aesthetic on a leaflet map), I get the following error:
Error in is_quosure(e2) : argument "e2" is missing, with no default
Here's an example of a reprex that produces a plot successfully. I first have to define a palette based on the domain of values i want to map, and then map them onto the leaflet. I'm using the nc
dataset that comes loaded with the sf package.
library(sf)
library(leaflet)
library(tidyverse)
pal <- colorFactor(palette = "plasma", domain = nc$BIR74)
nc %>%
leaflet(width = "100%") %>%
addPolygons(color = ~pal(BIR74))
When i wrap it in a function - even when i wrap the variable name in enquo - i get the is_quosure(e2) error.
plot_leaf_columns <- function(df, var) {
v <- enquo(var)
pal <- colorFactor(palette = "plasma", domain = pull(df, !!v) )
df %>%
leaflet(width = "100%") %>%
addPolygons(color = ~!!v)
}
Error in is_quosure(e2) : argument "e2" is missing, with no default
This feels like it has something to do with the interaction of !!
and the ~
that leaflet uses to map variables onto the graph.
HOWEVER, if i create a new "col" variable before creating the map, it works a treat. i can reproduce the graph from the first bit perfectly, and extend that to other columns in nc
, if i please.
plot_leaf_columns <- function(df, var) {
v <- enquo(var)
pal <- colorFactor(palette = "plasma", domain = pull(df, !!v))
df %>%
mutate(col = pal(!!v)) %>%
mutate(ugh = as.character(!!v)) %>%
leaflet(width = "100%") %>%
addPolygons(color = ~col)
}
plot_leaf_columns(nc, BIR74)
I have to do this with everything that relies on the input variable that i want to call in a leaflet function. For example, if i want to create labels, i have to first create a new character variable from the bang bang'd enquo()
, and call it later. This works:
plot_leaf_columns <- function(df, var) {
v <- enquo(var)
pal <- colorFactor(palette = "plasma", domain = pull(df, !!v))
df %>%
mutate(col = pal(!!v)) %>%
mutate(ugh = as.character(!!v)) %>%
leaflet(width = "100%") %>%
addPolygons(color = ~col,
label = ~ugh)
}
but if i were to replace the last line with
label = ~as.character(!!v))
it throws the same quosure error.
This is very curious to me!! I would greatly appreciate being pointed in the direction of any resources that might help me grok this behavior. it might just be a different way of calling !!
that I don't know yet. If not - is this the desired behavior by rlang / leaflet ? If so, I would be happy to help create vignettes or resources to point people toward this workaround. If there is a simpler way to program around leaflet using NSE / rlang, I would love to learn about it.
Thanks very much!