【问题标题】:dplyr / tidyevaluation: How to pass an expression in mutate as a string?dplyr / tidyevaluation:如何将 mutate 中的表达式作为字符串传递?
【发布时间】:2018-11-04 22:22:06
【问题描述】:

我想编写一个有两个输入的函数:一个新变量的名称和一个数学表达式。两个参数都是字符串。

此函数应采用 data.frame 并添加指定的新变量,该变量应为给定数学表达式的结果。

这是我尝试过的一个最小工作示例:

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.

当我用 expr() 将 mutate 行包裹在函数中时,我得到了

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

似乎A + B 周围的刻度不应该在那里,但我不知道如何摆脱它们。至少,enquo()quo_name() 没有帮助。

【问题讨论】:

    标签: r dplyr tidyeval


    【解决方案1】:

    我们可以有一个 quosure/quote 作为表达式,然后进行评估 (!!)。还有:=的lhs可以带字符串,所以我们不需要把'new_var'转成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
    

    如果我们真的想作为character 字符串传递,那么使用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
    

    【讨论】:

    • 感谢您添加第二部分。我真的需要使用parse_expr(),因为表达式来自data.frame。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 2017-11-19
    • 2018-09-22
    • 2018-10-22
    • 1970-01-01
    • 2018-04-01
    相关资源
    最近更新 更多