问题
Any assistance on this little conundrum would be mightily appreciated thanks.
I am trying to pass an argument to the tq_transmute
function from the tidyquant
package; the value for the argument is a function, however I would like to pass it as a string (out with the scope of the example below I’ll be passing it via a Shiny selectInput
).
I have tried every way I can think of to turn the string 'apply.quarterly' into the object apply.quarterly
accepted by the mutate_fun
argument. The commented lines are my failed attempts.
Ultimately, I would like to extend this concept to the other arguments also i.e. FUN = max
to FUN = ‘max’
.
library(tidyverse)
library(tidyquant)
library(rlang)
FANG %>%
group_by(symbol) %>%
tq_transmute(select = adjusted,
mutate_fun = apply.quarterly,
# mutate_fun = sym('apply.quarterly'),
# mutate_fun = syms('apply.quarterly'),
# mutate_fun = !!sym('apply.quarterly'),
# mutate_fun = !!!sym('apply.quarterly'),
# mutate_fun = eval(parse('apply.quarterly')),
# mutate_fun = eval(substitute('apply.quarterly')),
# mutate_fun = enquo('apply.quarterly'),
# mutate_fun = expr(!!enquo('apply.quarterly')),
# mutate_fun = quo('apply.quarterly'),
# mutate_fun = enquos('apply.quarterly'),
# mutate_fun = enquote('apply.quarterly'),
# mutate_fun = quote('apply.quarterly'),
# mutate_fun = substitute('apply.quarterly'),
# mutate_fun = parse('apply.quarterly'),
# mutate_fun = parse('apply.quarterly'),
# mutate_fun = ensym('apply.quarterly'),
# mutate_fun = rlang::as_function('apply.quarterly'),
# mutate_fun = rlang::as_closure('apply.quarterly'),
# mutate_fun = rlang::as_quosure('apply.quarterly'),
# mutate_fun = rlang::as_quosure('apply.quarterly'),
# mutate_fun = enexpr('apply.quarterly'),
# mutate_fun = enexprs('apply.quarterly'),
# mutate_fun = ensym('apply.quarterly'),
# mutate_fun = ensyms('apply.quarterly'),
# mutate_fun = eval_tidy('apply.quarterly'),
# mutate_fun = exprs('apply.quarterly'),
# mutate_fun = expr_deparse('apply.quarterly'),
# mutate_fun = expr_label('apply.quarterly'),
# mutate_fun = expr_label(substitute('apply.quarterly')),
# mutate_fun = expr_label(quote('apply.quarterly')),
# mutate_fun = parse_expr('apply.quarterly'),
# mutate_fun = quasiquotation('apply.quarterly'),
# mutate_fun = quotation('apply.quarterly'),
# mutate_fun = quotation('apply.quarterly'),
FUN = max,
col_rename = "max.close")
回答1:
It seems that function is a bit finicky for some reason. One way would be to change the call and then evaulate that. For example
myfun <- "apply.quarterly"
bquote(FANG %>%
group_by(symbol) %>%
tq_transmute(select = adjusted,
mutate_fun = .(as.name(myfun)),
FUN = max,
col_rename = "max.close")) %>%
eval()
or if you prefer rlang syntax
myfun <- "apply.quarterly"
quo(FANG %>%
group_by(symbol) %>%
tq_transmute(select = adjusted,
mutate_fun = !!sym(myfun),
FUN = max,
col_rename = "max.close")) %>%
eval_tidy()
Note that we have to treat the entire expression as rlang
quosure. Unless the tq_transmute
function was specifically written to handle rlang features like !!
then they won't work by default.
回答2:
You can use blast()
for quasiquotation with immediate evaluation
blast <- function(expr, env = caller_env()) {
eval_bare(enexpr(expr), env)
}
blast(list(!!!1:3))
#> [[1]]
#> [1] 1
#>
#> [[2]]
#> [1] 2
#>
#> [[3]]
#> [1] 3
Then
myfun <- "apply.quarterly"
blast(
FANG %>%
group_by(symbol) %>%
tq_transmute(
select = adjusted,
mutate_fun = !!sym(myfun),
FUN = max,
col_rename = "max.close"
)
)
回答3:
You can obtain the function from the string carrying the name of the function with get. The following works, for example:
s <- get("sum")
s(c(1,2,3))
来源:https://stackoverflow.com/questions/64452369/r-how-to-pass-a-function-as-a-string-inside-another-function