首页 > 解决方案 > 转换字符串以调用 dplyr 函数

问题描述

例子

我想编写一个执行以下操作的函数:

filter_and_compute <- function(df,
                               condition,
                               col_to_modify,
                               calculus) {
  df %>%
    filter( condition ) %>%
    mutate( col_to_modify = calculus ) %>%
    rbind(df %>% filter(! condition))
}

但是用字符串作为参数调用(除了df):

filter_and_compute(mtcars, "cyl == 4", "mpg", "2 * hp")

我做了什么

我制作了这个版本,但没有用,因为我将列名作为字符串操作:

filter_and_compute <- function(df,
                               filter_condition,
                               column_to_modify,
                               calculus) {
  enq_filter <-  enquo(filter_condition)
  enq_col_to_mod <- enquo(column_to_modify)
  enq_calculus <- enquo(calculus)
  (
    df
    %>% filter(!! enq_filter)
    %>% mutate(!! enq_col_to_mod := !! enq_calculus)
    %>% rbind( df %>% filter( ! (!! enq_filter)))
  )
}

filter_and_compute(mtcars, cyl == 4, mpg, 2 * cyl + hp)

我知道,rlang::sym但我不知道如何将它与不可预测的表达式一起使用,例如2 * cyl + hp...

标签: rtidyeval

解决方案


你可以eval使用parse_expr

library(dplyr)
library(rlang)

filter_and_compute <- function(df,
                               condition,
                               col_to_modify,
                               calculus) {
  df %>%
    filter(eval(parse_expr(condition))) %>%
    mutate(!! col_to_modify := eval(parse_expr(calculus))) %>%
    rbind(df %>% filter(! eval(parse_expr(condition))))

}

filter_and_compute(mtcars, "cyl == 4", "mpg", "2 * hp")

#     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#1  186.0   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#2  124.0   4 146.7  62 3.69 3.190 20.00  1  0    4    2
#3  190.0   4 140.8  95 3.92 3.150 22.90  1  0    4    2
#4  132.0   4  78.7  66 4.08 2.200 19.47  1  1    4    1
#5  104.0   4  75.7  52 4.93 1.615 18.52  1  1    4    2
#6  130.0   4  71.1  65 4.22 1.835 19.90  1  1    4    1
#7  194.0   4 120.1  97 3.70 2.465 20.01  1  0    3    1
#8  132.0   4  79.0  66 4.08 1.935 18.90  1  1    4    1
#9  182.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
#10 226.0   4  95.1 113 3.77 1.513 16.90  1  1    5    2
#11 218.0   4 121.0 109 4.11 2.780 18.60  1  1    4    2
#12  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#....

推荐阅读