Search code examples
rformularlang

Inside function F, use an argument to F as an argument to update()


I would like to have a function like my_lm, exemplified below:

library(rlang)

base_formula <- new_formula(lhs = quote(potato), 
                            rhs = quote(Sepal.Width + Petal.Length))

my_lm <- function(response) {
    lm(formula = update(old = base_formula, new = quote(response) ~ . ),
       data = iris)
}

my_lm(response = Sepal.Length)

But I am met with the following error:

Error in model.frame.default(formula = update(old = base_formula, new = enquo(response) ~  : 
  object is not a matrix 

I suspect I am misusing rlang, but I can't seem to figure out what combination of quoting, unquoting and formulating would solve this problem.

EDIT: desired output is as if I ran:

lm(formula = Sepal.Length ~ Sepal.Width + Petal.Length,

data = iris)

EDIT2: I should also clarify, I'm really interested in a solution that uses rlang to solve this problem through update more so than a solution that uses paste, gsub, and formula.


Solution

  • Here's something that works

    base_formula <- new_formula(lhs = quote(potato), 
                                rhs = quote(Sepal.Width + Petal.Length))
    
    my_lm <- function(response) {
      newf <- new_formula(get_expr(enquo(response)), quote(.))
      lm(formula = update(old = base_formula, new = newf),
         data = iris)
    }
    
    my_lm(response = Sepal.Length)
    

    It seems to be a bit of a mess because quosures are also basically formulas and you're trying to make a regular formula with them. And then new_formula doesn't seem to allow for !! expansion.

    If you are really just interested in changing the left hand side, something like this might be more direct

    my_lm <- function(response) {
      newf <- base_formula
      f_lhs(newf) <- get_expr(enquo(response))
      lm(formula = get_expr(newf),
         data = iris)
    }