Search code examples
rfunctionenvironment-variablesnsefixest

How to reference objects in a different environment inside a formula


I'm using fixest::feols() and I have a function I want to pass an argument to in order to subset the data using the subset = argument. However when keep getting the error: The argument 'subset' is a formula whose variables must be in the data set given in argument 'data'.

I have tried the following code:

library(fixest)

cars <- mtcars

my_fun <- function(data, hp.c.off) {
  
  feols(mpg ~ disp + drat,
        data = data,
        subset = ~ hp > substitute(hp.c.off))
}

my_fun(data = cars, 150)

My expected outcome would be the same as if one typed:

feols(mpg ~ disp + drat,
      data = cars,
      subset = ~ hp > 150)

I know I have to replace the value of hp.c.off before passing it onto a formula. And one could do this by creating a string expression first and then using as.formula() however, I was wondering if there is a better way to do programmatically build the expression that didn't require creating a string expression first and then converting it into a formula.

Thanks!


Solution

  • You can use rlang::new_formula(), with rlang::expr() to quote the rhs and !!rlang::enexpr() to capture and inject the hp.c.off argument.

    I don’t have fixest installed, but this demonstrates building the formula inside a function:

    library(rlang)
    
    cars <- mtcars
    
    my_fun <- function(data, hp.c.off) {
      new_formula(lhs = NULL, rhs = expr(hp > !!enexpr(hp.c.off)))
    }
    
    my_fun(data = cars, 150)
    # ~hp > 150
    # <environment: 0x1405e38>