enquo() inside a magrittr pipeline

我是研究僧i 提交于 2019-12-23 19:24:50

问题


I just would like to understand what's going wrong here. In the first case (working), I assign the enquo()-ted argument to a variable, in the second case, I use the enquoted argument directly in my call to 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

Edit Here are some more lines to think about :)

Wrapping the call into quo() it looks as if the expression to evaluate is "built" correctly

# 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))

If you tell this to eval_tidy, it works (it doesn't work without 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))

If you don't use the pipe, it also works

# 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))

Regarding the error message, this is what one gets, when one tries to pass types that are not supported by data.frames, eg.

mutate(df, value = function(x) x) # Error in mutate_impl(.data, dots) : Column value is of unsupported type closure

To me it looks as if the quosure in myfun_2 isn't evaluated by mutate, which is somehow interesting/non-intuitive behaviour. Do you think I should report this to the developers?


回答1:


This limitation is solved in rlang 0.2.0.

Technically: The core of the issue was that magrittr evaluates its arguments in a child of the current environment. This is this environment that contains the . pronoun. As of 0.2.0, capture of arguments with enquo() and variants is now lexically scoped, which means it looks up the stack of parent environments to find the argument to capture. This solves the magrittr problem.



来源:https://stackoverflow.com/questions/49074569/enquo-inside-a-magrittr-pipeline

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!