【问题标题】:Programming a function for "lm" using tidyeval使用 tidyeval 为“lm”编写函数
【发布时间】:2018-04-02 17:37:17
【问题描述】:

我正在尝试使用 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)

但是,我还没有弄清楚如何使用tidyevalrlang 编写这个函数。我假设substitute 应该替换为enquo,而eval 应该替换为!!。 Hadley 的 Adv-R 中有一些提示,但我想不通。

【问题讨论】:

  • 你为什么要这样做?
  • 为了使用 dplyr 函数进行编程,使用 tidyeval/rlang 很有用,我只想使用一个系统。 Beides,我想向一些学生解释,我认为只使用一个系统更容易,更一致。
  • 鉴于 lm() 不使用与 dplyr 相同的 NSE 形式,我认为用 rlang 打它不会有帮助。

标签: r lm tidyeval


【解决方案1】:

这是未来可能会在 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)

棘手的部分是:

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

  • 我们需要检查用户没有取消引用引号。 lm() 和 co 不支持这些。 quo_expr() 将所有 quosures 展平,并在发现某些时选择性地发出警告。

【讨论】:

  • 谢谢,这就是我想要的。尽管如此,我仍然需要把头绕过去:)
猜你喜欢
  • 2020-05-31
  • 2018-02-02
  • 1970-01-01
  • 1970-01-01
  • 2019-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-05
相关资源
最近更新 更多