Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert formula to function, or apply the formula to some values?

I have a function that needs to expect a formula as an input, in the form of y~x, for example. Then, I need to pass a series of x-values into that formula to get out the y's.

For example, if my formula is y~x^2, and my series of x-values is (1,2,3,4), then I should expect (1,4,9,16) as output.

Say I have the formula like this: formula1 <- y~x:

Here's what I've tried thus far:

  • Converting the formula into a function: as.function(formula1)
  • Using model.frame and model.matrix like so:

Like so:

formula1 <- y~x^2 
x <- c(1,2,3,4)
my_data <- data.frame("x" = x, "y" = rep(0,length(x))) 
model_frame <- model.frame(formula1, data = my_data)
my_design_matrix <- model.matrix(formula1, model_frame)
  • I tried using nls2, but I don't have any parameters to optimize, so I don't see the point.

What can I use for this?

Here are the resources I consulted:
How to apply a formula to a vector in R?

Pass formula to function in R?

like image 335
makansij Avatar asked Apr 17 '16 18:04

makansij


2 Answers

I'm not sure if this is the most elegant way but it should do as you require:

The idea is to extract the right hand side of the formula object and parse it as a string. The result then may be evaluated.

as.function <- function(formula) {
    cmd <- tail(as.character(formula),1)
    exp <- parse(text=cmd)
    function(...) eval(exp, list(...))
}

Note however that there are valid formulas that may not be evaluated this way, for example y ~ a:c.

which gives us

> f <- as.function(y ~ x^2)
> f(x=1:10)
 [1]   1   4   9  16  25  36  49  64  81 100

If you like to submit a data.frame to the generated function you could just do

as.function <- function(formula) {
    cmd <- tail(as.character(formula),1)
    exp <- parse(text=cmd)
    function(df) eval(exp, df)
}

and get

> f <- as.function(y ~ x^2)
> f(data.frame(x=1:10))
 [1]   1   4   9  16  25  36  49  64  81 100
like image 89
Thilo Avatar answered Oct 21 '22 00:10

Thilo


purrr::as_mapper maps one sided formulas to functions:

fn <- as_mapper(~ .^2)
fn(2) # gives 4 

as_mapper(\(x){x^2}) also works so you can create functions that take formulas or functions.

my_func <- \(x,fn){ as_mapper(fn)(x) }
my_func(2,~.^2)      # gives 4
my_func(2,\(x){x^2}) # gives 4
like image 29
Thomas Luechtefeld Avatar answered Oct 21 '22 00:10

Thomas Luechtefeld