繁体   English   中英

R:具有嵌套函数的非标准评估

[英]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:将表达式传递给内部函数

最简单的方法是使用rlangtidyverse函数与准引用兼容:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM