在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动词中允许自定义“宏”。
答案 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)
)