The problem is buried inside of recode_factor. It is that only functions that are implemented to use quosures can properly interpret !!!. recode_factor itself is implemented to use quosures but the c() which it uses is not.
Here is where the problem is in recode_factor:
dplyr::recode_factor
#> function (.x, ..., .default = NULL, .missing = NULL, .ordered = FALSE)
#> {
#> recoded <- recode(.x, ..., .default = .default, .missing = .missing)
# -----------------------------The problem is the c() function here ---
#> all_levels <- unique(c(..., recode_default(.x, .default,
#> recoded), .missing))
#> recoded_levels <- if (is.factor(recoded))
#> levels(recoded)
#> else unique(recoded)
#> levels <- intersect(all_levels, recoded_levels)
#> factor(recoded, levels, ordered = .ordered)
#> }
#> <environment: namespace:dplyr>
Created on 2018-03-03 by the reprex package (v0.2.0).
The problem is in the Combine, c(), function. Although in !!! layer_key, !!! looks like an operator or in !!!(layer_key) it looks like a function it is neither.
It depends on the function getting the !!! layer_key in a ... argument to do something like enquo(...) so that standard evaluation is bypassed. It is enquo(or one of it's friends) that interprets !!! to turn a list into individual dot arguments.
But c() is a primitive function so it just does standard evaluation of !!! level_key which, in effect, produces a syntax kind of error.
Here is an example of a function that tries to use !!! with c()
suppressPackageStartupMessages(library(tidyverse))
f2 <- function(...) {
c(...)
}
level_key <- list("Be", "Cool", "Amigo") %>% set_names(c("B", "C", "A")) # set factor re-level
f2(!!! level_key)
#> Error in !level_key: invalid argument type
Created on 2018-03-03 by the reprex package (v0.2.0).
I don't see a workaround for this.