[英]R: non-standard evaluation with nested functions
我在一个数据帧上有一个函数f1,它调用另一个函数f2,然后对f2的输出进行填充。 f2本身可以交互工作,但是当f1调用它时如何使它运行?
f1 <- function(x, y) {
z <- f2(x, y)
# do stuff with z
w <- z
return(w)
}
f2使用subset()取消选择某些列:
f2 <- function(x, y) {
y <- substitute(y)
subset(x, select = -eval(y))
}
如您所见,f2可以交互工作。 我不在乎,但是我确实希望它在被f1调用时能够正常工作。
# This works fine interactively (but I don't care about that)
f2(mtcars,mpg)
# This is what I want to work
f1(mtcars,mpg)
Error in -eval(y) : invalid argument to unary operator
我宁愿不更改f1或其参数。 如何重新编写f2,使其在f1中起作用?
这是一个类似的问题,我无法将其应用于上下文: R:将表达式传递给内部函数
最简单的方法是使用rlang
和tidyverse
函数与准引用兼容:
library(dplyr)
library(rlang)
f1 <- function(x, y) {
z <- f2(x, -!!enquo(y))
# do stuff with z
w <- z
return(w)
}
f2 <- function(x, y) {
select(x, !!enquo(y))
}
f1(mtcars,mpg)
# cyl disp hp drat wt qsec vs am gear carb
# Mazda RX4 6 160.0 110 3.90 2.620 16.46 0 1 4 4
# Mazda RX4 Wag 6 160.0 110 3.90 2.875 17.02 0 1 4 4
# Datsun 710 4 108.0 93 3.85 2.320 18.61 1 1 4 1
# ...
这适用于基数R:
f1 <- function(x, y) {
z <- f2(x, substitute(y))
# do stuff with z
w <- z
return(w)
}
f2 <- function(x, y) {
eval(substitute(subset(x, select = -Y), list(Y = y)))
}
f1(mtcars,mpg)
# cyl disp hp drat wt qsec vs am gear carb
# Mazda RX4 6 160.0 110 3.90 2.620 16.46 0 1 4 4
# Mazda RX4 Wag 6 160.0 110 3.90 2.875 17.02 0 1 4 4
# Datsun 710 4 108.0 93 3.85 2.320 18.61 1 1 4 1
# ...
使用较新版本的rlang
0.4.0
,我们可以使用{{...}}
(curly-curly)来rlang
评估
library(rlang)
f1 <- function(x, y) {
z <- f2(x, -{{y}})
# do stuff with z
w <- z
return(w)
}
f2 <- function(x, y) {
select(x, {{y}})
}
f1(mtcars,mpg) %>%
head
# cyl disp hp drat wt qsec vs am gear carb
#Mazda RX4 6 160 110 3.90 2.620 16.46 0 1 4 4
#Mazda RX4 Wag 6 160 110 3.90 2.875 17.02 0 1 4 4
#Datsun 710 4 108 93 3.85 2.320 18.61 1 1 4 1
#Hornet 4 Drive 6 258 110 3.08 3.215 19.44 1 0 3 1
#Hornet Sportabout 8 360 175 3.15 3.440 17.02 0 0 3 2
#Valiant 6 225 105 2.76 3.460 20.22 1 0 3 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.