使用tidyeval为“ lm”编程功能

Seb*_*uer 5 r lm tidyeval

我正在尝试使用tidyeval(非标准评估)围绕“ lm”编写一个函数。使用基本R NSE,它的工作原理是:

lm_poly_raw <- function(df, y, x, degree = 1, ...){
  lm_formula <-
    substitute(expr = y ~ poly(x, degree, raw = TRUE),
               env = list(y = substitute(y),
                          x = substitute(x),
                          degree = degree))
  eval(lm(lm_formula, data = df, ...))
}

lm_poly_raw(mtcars, hp, mpg, degree = 2)
Run Code Online (Sandbox Code Playgroud)

但是,我还没有弄清楚如何使用tidyeval和编写此函数rlang。我认为substitute应该用代替enquo,并用代替!!。哈德利的Adv-R有一些提示,但我不知道。

Lio*_*nry 6

这是将来可能在rlang中使用的一种公式构造函数:

f <- function(x, y, flatten = TRUE) {
  x <- enquo(x)
  y <- enquo(y)

  # Environments should be the same
  # They could be different if forwarded through dots
  env <- get_env(x)
  stopifnot(identical(env, get_env(y)))

  # Flatten the quosures. This warns the user if nested quosures are
  # found. Those are not supported by functions like lm()
  if (flatten) {
    x <- quo_expr(x, warn = TRUE)
    y <- quo_expr(y, warn = TRUE)
  }

  new_formula(x, y, env = env)
}

# This can be used for unquoting symbols
var <- "cyl"
lm(f(disp, am + (!! sym(var))), data = mtcars)
Run Code Online (Sandbox Code Playgroud)

棘手的部分是:

  • 如果通过不同层次的转发,LHS和RHS可能来自不同的环境...。我们需要检查一下。

  • 我们需要检查用户是否取消取消报价。lm()并且不支持这些。quo_expr()展平所有的quassures,并选择警告(如果发现)。