使用tidyeval为“lm”编程函数

时间:2017-10-21 20:44:38

标签: r lm tidyeval

我正在尝试使用tidyeval(非标准评估)在“lm”周围编写一个函数。使用base 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有一些提示,但我无法理解。

1 个答案:

答案 0 :(得分:4)

以下是可能在未来的rlang中使用的公式构造函数:

const data = {
    data: {
        user: {
            data: {
                firstName: 'joe',
                data: {surname: 'bloggs'}
            }
        },
        message: 'this is a message'
    }
};

const stripData = (data, root = true) => {
    let result = {};
    Object.keys(data).forEach(key => {
        let value = data[key];
        if (typeof value === 'object') {
            value = stripData(value, false);
            if (key === 'data') {
                result = Object.assign(result, root ? {data: value} : value);
            } else {
                result[key] = value;
            }
        } else {
            result[key] = value;
        }
    });
    return result;
};

console.log(stripData(data));

棘手的部分是:

  • 如果通过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()会使所有情况变得扁平化,并且如果找到某些情况,则可选择发出警告。