I want to write a function that has two inputs: The name of a new variable and a mathematical expression. Both arguments come as strings.
This function should take a data.frame and add the specified new variable which should be the result of the given mathematical expression.
This is a minimal working example of what I tried:
df <- tibble(A = 1:10, B = 1:10)
new_var <- "C"
expression <- "A + B"
example_fun <- function(new_var, expression) {
new_var_sym <- sym(new_var)
expression_sym <- sym(expression)
mutate(df, !! new_var_sym := !! expression_sym)
}
example_fun(new_var, expression)
This yields the following error:
Error in mutate_impl(.data, dots) : Binding not found: A + B.
When I wrap the mutate line within the function with expr()
, I get
mutate(df, `:=`(C, `A + B`))
It seems as if the ticks around A + B
should not be there, but I could not figure out how to get rid of them. At least, enquo()
and quo_name()
did not help.
We can have a quosure/quote as expression and then do the evaluation (!!
). Also, the lhs of :=
can take string, so we don't need to convert the 'new_var' to symbol
library(tidyverse)
library(rlang)
expression <- quo(A + B)
example_fun <- function(new_var, expression) {
df %>%
mutate(!! new_var := !! expression)
}
example_fun(new_var, expression)
# A tibble: 10 x 3
# A B C
# <int> <int> <int>
# 1 1 1 2
# 2 2 2 4
# 3 3 3 6
# 4 4 4 8
# 5 5 5 10
# 6 6 6 12
# 7 7 7 14
# 8 8 8 16
# 9 9 9 18
#10 10 10 20
If we really wanted to pass as character
strings, then use parse_expr
expression <- "A + B"
example_fun <- function(new_var, expression) {
df %>%
mutate(!! new_var := !! parse_expr(expression))
}
example_fun(new_var, expression)
# A tibble: 10 x 3
# A B C
# <int> <int> <int>
# 1 1 1 2
# 2 2 2 4
# 3 3 3 6
# 4 4 4 8
# 5 5 5 10
# 6 6 6 12
# 7 7 7 14
# 8 8 8 16
# 9 9 9 18
#10 10 10 20
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With