rlang::sym in anonymous functions

烈酒焚心 提交于 2019-12-05 01:01:16

Note that the following code has rlang::sym() inside an anonymous function and works as intended:

map2(c("x1","x2"), c("x2","x1"), function(a, b){
  data %>%
    mutate(y1 = !!rlang::sym(a)) %>%
    mutate(y2 = !!rlang::sym(b)) %>%
    select(y1, y2, val)})

The original issue has to do with the unquoting operator !! and its precedence relative to anonymous function creation inside non-standard evaluation (NSE) functions, such as mutate. Consider a nested data frame

XX <- data_frame( dfs = list(
  data_frame( x = letters[1:3], y = 1:3 ),
  data_frame( x = letters[4:6], y = 4:6 )) )

If I attempt to select the first column inside each of the internal data frames using

XX %>% mutate( dfs1 = map( dfs, function(df) {
  i <- 1
  df %>% select(!!i)} ))

I get an object 'i' not found error, because the !! unquoting happens relative to the outer mutate, before the environment for the anonymous function (containing select) is created. If I move the anonymous function outside of mutate

map( XX$dfs, function(df) {
  i <- 1
  df %>% select(!!i)} )

it works without problems because map follows standard evaluation rules and the anonymous function environment is now created before the unquoting.


The help page for !! states that

The !! operator unquotes its argument. It gets evaluated immediately in the surrounding context.

This implies that when you write a complex NSE expression, such as select inside mutate, the unquoting will take place in the environment of the expression as a whole. As pointed out by @lionel in the comments, the unquoting in NSE takes precedence over other things, such as creation of anonymous function environments.

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