0

我正在尝试根据函数的参数中的 quosures 制作“新表达式”,但不确定如何准确制作这个新表达式。

这是一个示例,其中我传递了一个分子和分母,理想情况下会在两者上进行突变,但也希望在将它们分开的地方进行突变:

df <- tibble(
  g1 = c(1, 1, 2, 2, 2),
  g2 = c(1, 2, 1, 2, 1),
  a = sample(5), 
  b = sample(5)
)

my_divide <- function(df, numerator, denominator) {
  numerator <- enquo(numerator)
  denominator <- enquo(denominator)

  df %>%
    mutate(p = !!numerator / !!denominator)
}

my_divide(df, g1 , g2)

这失败并出现以下错误:

Error in !denominator : invalid argument type 

我可以轻松地将表达式作为它自己的参数传递并 enquo() 它,但这不适用于更多表达式。我还可以从基本 quosures 在数据框中创建临时列,然后直接计算表达式,但这似乎太冗长了。我想有一种更简单的方法可以做到这一点

4

3 回答 3

2

1) /具有更高的优先级,!但我们想要!更紧密地绑定,因为我们想要!在除法之前应用,而不是之后。把括号放在周围!!numerator,然后它就会起作用。?Syntax有关R 语言使用的优先规则的文档,请参阅。

2)另一种可能性,但没有 rlang/tidyeval 是:

my_divide <- function(df, numerator, denominator = 1) {
  eval.parent(substitute(
   df %>% mutate(p = numerator / denominator)
  ))
}

my_divide(df, g1 / g2)
my_divide(df, g1, g2)
于 2018-02-08T23:33:55.253 回答
1

使用反引号调用除法函数。

my_divide <- function(df, numerator, denominator) {
  n <- enquo(numerator)
  d <- enquo(denominator)

  df %>%
    mutate(p = `/`(!!n, !!d))
}

my_divide(df, g1 , g2)
于 2018-02-09T07:23:44.597 回答
0

一种选择是将其作为带引号的表达式传递以供以后评估

my_divide <- function(df, exprs) {  

 df %>%
    mutate(p = !! exprs) 
 }

my_divide(df, quote(g1/ g2))
# A tibble: 5 x 5
#    g1    g2     a     b     p
#  <dbl> <dbl> <int> <int> <dbl>
#1  1.00  1.00     5     2 1.00 
#2  1.00  2.00     2     4 0.500
#3  2.00  1.00     3     1 2.00 
#4  2.00  2.00     4     5 1.00 
#5  2.00  1.00     1     3 2.00 
于 2018-02-09T02:31:19.957 回答