dplyr/tidyevaluation:如何将表达式作为字符串传递给mutate函数?

17
我想编写一个函数,它有两个输入参数:新变量的名称和数学表达式。这两个参数都是以字符串形式给出的。
该函数应接收一个数据框,并添加指定的新变量,该变量应为给定数学表达式的结果。
以下是我尝试的最小工作示例:
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)

这导致了以下错误:

Error in mutate_impl(.data, dots) : Binding not found: A + B.

当我在函数中的mutate行周围包裹expr()时,我得到了:

mutate(df, `:=`(C, `A + B`))

看起来似乎在 A + B 周围的引号不应该在那里,但我无法弄清楚如何摆脱它们。至少,enquo()quo_name() 没有帮助。

1个回答

20

我们可以使用引述/引号作为表达式,然后进行求值(!!)。此外,:=的lhs可以接受字符串,因此我们不需要将'new_var'转换为符号。

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
如果我们真的想将其传递为“字符”字符串,则使用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

2
感谢您添加第二部分。我确实需要使用parse_expr(),因为表达式来自数据框。 - der_grund

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接