奇怪的dplyr + NSE:在mutate中的自定义函数中使用NSE

时间:2018-07-20 17:30:53

标签: r dplyr nse

dplyr::mutate内的自定义函数中使用NSE时,我偶然发现了一个问题。考虑以下代码:

require(tidyverse)

f <- function(var) {
  varname <- deparse(substitute(var))
  v1      <- as.name(sprintf("%s.Width", varname))
  v2      <- as.name(sprintf("%s.Length", varname))
  return(substitute(v1 + v2))
}

iris %>% 
  mutate(
    test = f(Sepal) %>% eval()
  )

ff <- function(var) {
  varname <- deparse(substitute(var))
  v1      <- as.name(sprintf("%s.Width", varname))
  v2      <- as.name(sprintf("%s.Length", varname))
  substitute(v1 + v2) %>% eval.parent(n = 1)
}

iris %>% 
  mutate(
    test = ff(Sepal)
  )

这里f可以正常工作,但是需要外部调用eval()才能在mutate()环境中执行代码。 这当然有点丑陋,并导致很多样板代码。在进行这项工作时,我最好的猜测是ff,它试图在其调用环境中评估构造的表达式,我希望它是mutate()环境。但是,这将引发未找到变量错误。 关于如何使这项工作以及潜在的问题有什么想法?本质上,我希望在dplyr动词中允许自定义“宏”。

1 个答案:

答案 0 :(得分:0)

使用!!整齐的eval“ unquote”运算符:

ff <- function(var) {
  varname <- deparse(substitute(var))
  v1      <- as.name(sprintf("%s.Width", varname))
  v2      <- as.name(sprintf("%s.Length", varname))
  substitute(v1 + v2)
}

iris %>% 
  head() %>% 
  mutate(
    test = !! ff(Sepal)
  )