I have two functions:
Worker
that does the jobBoss
that calls the "Worker" and ask it to execute given function called by name
If I call Worker
directly it receives function body and its name so it can use both. But if I call the Worker
through the Boss
, the Boss
masks name of the function from the Worker
as FUN
require(magrittr)
require(dplyr)
df <- data.frame(one = c(1,1,1), two = c(1,3,NA))
Worker <- function(df, feature, FUN, ...) {
newvarname <- paste0(substitute(FUN), feature)
df %>% mutate(!!newvarname := FUN(!!as.name(feature), ...))
}
Boss <- function(df, feature, FUN, ...) {
df %>% Worker(feature, FUN, ...)
}
Boss(df, "two", mean, na.rm = T)
# one two FUNtwo
# 1 1 1 2
# 2 1 3 2
# 3 1 NA 2
Worker(df, "one", mean)
# one two meanone
# 1 1 1 1
# 2 1 3 1
# 3 1 NA 1
I tired to play with quote/quo/enquo/substitute/get/match.fun
, but nothing helped. Does it mean, that R cannot pass a whole function object - both name and body - as an argument?
Here is one way to handle it with some rlang
:
library(rlang)
df <- data.frame(one = c(1,1,1), two = c(1,3,NA))
Worker <- function(df, feature, FUN, ...) {
if (!is_quosure(FUN)) {
fun_q <- quo(FUN)
newvarname <- paste0(substitute(FUN), feature)
}
else {
fun_q <- FUN
newvarname <- paste0(quo_text(fun_q), feature)
}
df %>% mutate(!!newvarname := eval(fun_q)(!!as.name(feature), ...))
}
Boss <- function(df, feature, FUN, ...) {
fun_q <- enquo(FUN)
df %>% Worker(feature, fun_q, ...)
}
Boss(df, "two", mean, na.rm = T)
one two meantwo
1 1 1 2
2 1 3 2
3 1 NA 2
Worker(df, "one", mean)
one two meanone
1 1 1 1
2 1 3 1
3 1 NA 1