3

我只是想了解这里出了什么问题。在第一种情况下(工作),我将enquo()-ted 参数分配给一个变量,在第二种情况下,我直接在调用mutate.

library("dplyr")
df <- tibble(x = 1:5, y= 1:5, z = 1:5)

# works
myfun <- function(df, transformation) {
  my_transformation <- rlang::enquo(transformation)
  df %>% 
    gather("key","value", x,y,z) %>% 
    mutate(value = UQ(my_transformation))
}
myfun(df,exp(value))

# does not work
myfun_2 <- function(df, transformation) {
  df %>% 
    gather("key","value", x,y,z) %>% 
    mutate(value = UQ(rlang::enquo(transformation)))
}
myfun_2(df,exp(value))
#>Error in mutate_impl(.data, dots) : Column `value` is of unsupported type closure

编辑 这里还有一些需要考虑的行:)

将调用包装到 quo() 中,看起来好像要评估的表达式是正确“构建”的

# looks as if the whole thing should be working
myfun_2_1 <- function(df, transformation) {
  quo(df %>% 
    gather("key","value", x,y,z) %>% 
    mutate(value = UQ(rlang::enquo(transformation))))
}
myfun_2_1(df,exp(value))

如果你告诉它eval_tidy,它可以工作(没有 quo() 就不能工作)

# works
myfun_2_2 <- function(df, transformation) {
  eval_tidy(quo(df %>% 
    gather("key","value", x,y,z) %>% 
    mutate(value = UQ(rlang::enquo(transformation)))))
}
myfun_2_2(df,exp(value))

如果你不使用管道,它也可以工作

# works
myfun_2_3 <- function(df, transformation) {
  mutate(gather(df,"key","value", x,y,z), value = UQ(rlang::enquo(transformation)))
}
myfun_2_3(df,exp(value))

关于错误消息,当人们尝试传递 data.frames 不支持的类型时,这就是所得到的,例如。

mutate(df, value = function(x) x) # mutate_impl(.data, dots) 中的错误:列value的闭包类型不受支持

对我来说,似乎 myfun_2 中的 quosure 不是由 评估的mutate,这在某种程度上是有趣/不直观的行为。你认为我应该向开发人员报告这个吗?

4

1 回答 1

6

这个限制在 rlang 0.2.0 中得到解决。

从技术上讲:问题的核心是 magrittr 在当前环境的子节点中评估其参数。这是包含.代词的环境。从 0.2.0 开始,使用和变体捕获参数enquo()现在是词法范围的,这意味着它会查找父环境的堆栈以找到要捕获的参数。这解决了 magrittr 问题。

于 2018-03-05T10:39:35.837 回答