magrittr 管道内的 enquo()
enquo() inside a magrittr pipeline
我只是想了解这里出了什么问题。
在第一种情况下(工作),我将 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() 中,看起来好像要评估的表达式是 "built" 正确
# 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 不支持的类型时得到的信息,例如
变异(df,值=函数(x)x)
# mutate_impl(.data, dots) 中的错误:列 value
的类型不受支持 closure
对我来说,myfun_2 中的 quosure 似乎没有被 mutate
评估,这在某种程度上是 interesting/non-intuitive 行为。您认为我应该向开发人员报告此事吗?
此限制已在 rlang 0.2.0 中解决。
从技术上讲:问题的核心是 magrittr 在当前环境的子环境中评估其参数。这是包含 .
代词的环境。从 0.2.0 开始,使用 enquo()
和变体捕获参数现在是词法范围的,这意味着它会查找父环境的堆栈以找到要捕获的参数。这解决了 magrittr 问题。
我只是想了解这里出了什么问题。
在第一种情况下(工作),我将 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() 中,看起来好像要评估的表达式是 "built" 正确
# 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 不支持的类型时得到的信息,例如
变异(df,值=函数(x)x)
# mutate_impl(.data, dots) 中的错误:列 value
的类型不受支持 closure
对我来说,myfun_2 中的 quosure 似乎没有被 mutate
评估,这在某种程度上是 interesting/non-intuitive 行为。您认为我应该向开发人员报告此事吗?
此限制已在 rlang 0.2.0 中解决。
从技术上讲:问题的核心是 magrittr 在当前环境的子环境中评估其参数。这是包含 .
代词的环境。从 0.2.0 开始,使用 enquo()
和变体捕获参数现在是词法范围的,这意味着它会查找父环境的堆栈以找到要捕获的参数。这解决了 magrittr 问题。