3

I'm working with formulas in a package, and I'd like to remove all non-numeric terms.

My problem is that, since the base formula may contain operations, I cannot evaluate some terms directly.

Here is a reprex:

datax=mtcars
op = c("mpg", "log(mpg)", "ifelse(mpg>2, '>2', '<=2')")
sapply(op, function(x){ is.numeric(datax[[x]]) })
#T,F,F
sapply(op, function(x){ is.numeric(with(data, get(x))) })
#Error in get(x) : object 'log(mpg)' not found

#Expected output:
#T,T,F

I know I could use attach(datax) but this function is highly not recommended and I'd rather avoid it.

Is there a way to evaluate the operation in the context of the dataframe so I can test if the result is numeric or not?

NB: I'm not sure my title should be about evaluation or formula terms dropping, feel free to propose an edit.

Dan Chaltiel
  • 7,811
  • 5
  • 47
  • 92

2 Answers2

2

One option is to use eval(parse()), i.e.

sapply(op, function(i) {is.numeric(with(mtcars, eval(parse(text = i))))})

#                       mpg                   log(mpg) ifelse(mpg>2, '>2', '<=2') 
#                      TRUE                       TRUE                      FALSE 
Sotos
  • 51,121
  • 6
  • 32
  • 66
2

Using tidyverse

library(purrr)
library(rlang)
map_lgl(parse_exprs(op), ~ eval_tidy(.x, data = datax) %>%
              is.numeric)
#[1]  TRUE  TRUE FALSE
akrun
  • 874,273
  • 37
  • 540
  • 662