I have defined a function which produces a ggplot chart, where the y-variable can either be a level or a percentage, so I have included an if-else to amend the options appropriately. I then run the chart through ggplotly to produce an interactive version, but the hover-over text label does not work as intended. As shown in the picture, the label just prints my function instead of showing the y-value as intended.
I have struggled to find the right approach and think that I am supposed to use eval
, quote
or expression
in some way, but don't understand how it all fits together. What I do know is that without using e.g. quote
, I get an error saying the object values
does not exist, which suggests that part of the function is evaluated without being told values
is a column within my dataset.
Here is my reprex:
library(tidyverse) #for dplyr
library(ggplot2) #for chart
library(scales) #for axis label
library(plotly) #for interactive chart
# dataset
dataset <- data.frame(geography_name=c("a","b","c","d","e","f"),
values=c(2,3,4,5,6,7))
# custom helper functions
perc_form = function(x, d=1) sprintf(paste0("%1.",d,"f"), x)
value_form = function(x,s=2,d= -1) format(signif(round(as.numeric(x), d),s), big.mark=",")
# function producing ggplot chart
barchart <- function( data_set = dataset,
x_var = geography_name,
y_var = values,
bar_stat_type=NULL) {
# Set axis type dependent on variable format
if (bar_stat_type=="pct") {
y_var_label <- paste0("Rate: ",quote(perc_form({{y_var}})),"%")
label_form <- (percent_format(accuracy=1))
} else if (bar_stat_type=="money") {
y_var_label <- paste0("Level: £",quote(value_form({{y_var}})))
label_form <- (comma_format())
}
# Chart
barchart <- data_set %>%
ggplot(mapping = aes(x = {{x_var}},
y = {{y_var}},
text = paste0(geography_name, "\n",
eval(y_var_label), "\n")))+
geom_bar(stat = "identity", position = position_dodge(), width = 0.4)+
scale_y_continuous(labels = eval(label_form)) #this evaluation works
return(barchart)
}
# ggplot chart is produced fine
gg <- barchart(bar_stat_type="money")
gg
# ggplotly chart does not have correct hover-over labels
ggplotly(gg)
There is no need for quote
or eval
. Simply make you y_var_label
s functions which can be called inside your ggplot2
code:
library(ggplot2)
library(scales)
library(plotly)
barchart <- function(data_set = dataset,
x_var = geography_name,
y_var = values,
bar_stat_type = NULL) {
if (bar_stat_type == "pct") {
y_var_label <- function(x) paste0("Rate: ", perc_form(x), "%")
label_form <- percent_format(accuracy = 1)
} else if (bar_stat_type == "money") {
y_var_label <- function(x) paste0("Level: £", value_form(x))
label_form <- comma_format()
}
data_set %>%
ggplot(mapping = aes(
x = {{ x_var }},
y = {{ y_var }},
text = paste0(
geography_name, "\n",
y_var_label({{ y_var }}), "\n"
)
)) +
geom_bar(stat = "identity", position = position_dodge(), width = 0.4) +
scale_y_continuous(labels = label_form)
}
gg <- barchart(bar_stat_type = "money")
ggplotly(gg)