I have a working function with and if else
that was largely duplicated code, so I'm trying to get rid of the duplication by using an in line if else statement. What's strange to me is that the same snippet works in one place of the code but not in the other.
library(dplyr)
library(highcharter)
plot_highchart <- function(.data,
group_by_variable = TRUE,
x_value = "Year",
y_value = "total",
.group = service,
.stacking = "normal",
chart_type = "column") {
.data %>%
# this next line works. If you comment out the hchart part it will group by and summarize
group_by(Year, if (group_by_variable == TRUE) !!rlang::enquo(.group) else NULL) %>%
summarize(total = sum(Spending)) %>%
hchart(chart_type, hcaes(x = !!rlang::ensym(x_value),
y = !!rlang::ensym(y_value),
group = if (group_by_variable == TRUE) !!rlang::ensym(.group) else NULL))
# same bit as before but I get an error
}
Here's the error I get when I try to run this:
Error: Problem with `mutate()` input `group`.
x object 'group_by_variable' not found
i Input `group` is `if (group_by_variable == TRUE) service else NULL`.
Which I find strange because group_by_variable
was found before. Not really sure where to go from here.
Here's the dput on the data:
structure(list(Year = c(2016, 2016, 2016, 2016, 2016, 2016),
service = structure(c(10L, 10L, 10L, 10L, 10L, 10L), .Label = c("Defense Logistics Agency",
"Chemical and Biological Defense Program", "Defense Information Systems Agency",
"United States Special Operations Command", "Office of the Secretary Of Defense",
"Missile Defense Agency", "Defense Advanced Research Projects Agency",
"Navy", "Army", "Air Force"), class = "factor"), Spending = c(0.803,
0.628, 0.2, 23.72, 4.782, 12.152)), class = c("tbl_df", "tbl",
"data.frame"), row.names = c(NA, -6L))
hcaes()
captures the expression you provide to group
and delays its evaluation. However, the expression undergoes a series of changes in the highcharter package. One of these steps assigns the global environment to be the evaluation context, which then causes the R interpreter to look for group_by_variable
in the global scope, and not in your function where it is defined.
One workaround is to pull the if
statement outside haes()
, so group_by_variable
doesn't get captured by the function as part of the expression to evaluate:
plot_highchart <- function(.data,
group_by_variable = TRUE,
x_value = "Year",
y_value = "total",
.group = service,
.stacking = "normal",
chart_type = "column") {
g <- if (group_by_variable == TRUE) list(group = rlang::ensym(.group))
else NULL
.data %>%
group_by(Year, !!g[[1]]) %>%
summarize(total = sum(Spending)) %>%
hchart(chart_type, hcaes(x = !!rlang::ensym(x_value),
y = !!rlang::ensym(y_value),
!!!g))
}
plot_highchart( .data ) # Works
plot_highchart( .data, group_by_variable=FALSE ) # Also works
Here, I am also storing the grouping symbol inside a named list and then using that list with !!!
. This is necessary to handle the group_by_variable == FALSE
case, because:
hcaes( x = ..., y = ... ) # Works
hcaes( x = ..., y = ..., group = NULL ) # Doesn't