Home > Software engineering >  R apply a formula in a for loop
R apply a formula in a for loop

Time:11-19

I would like to create a function in which a mathematical formula is set as argument (with only two possible variables) and use this formula within two nested loop. The idea is to be able to change the formula as I would like to create y values based on the formula. This is what I have done but I cannot apply the formula:

foo <- function(formula = y~a-b){
formula = as.formula(y ~a -b)
formula = formula[[3:length(formula)]]
result = NULL
for (a in 1:30) {
 for(b in 1:30){
  result = c(result, noquote(formula))
 }
}
return(result)
}

CodePudding user response:

Create a template fun and then insert the formula into its body.

foo <- function(formula = y ~ a - b) {
  fun <- function(a, b) {}
  body(fun) <- formula[[length(formula)]]
  result <- NULL
  for (a in 1:30) {
    for(b in 1:30) {
      result = c(result, fun(a, b))
    }
  }
  return(result)
}

# test
result <- foo()

CodePudding user response:

I like the solution that G. Grothendieck provided. Here is another way to do this, where you have foo() take a character representation of the formula, and use as.function()

foo <- function(f) as.function(alist(a=,b=,eval(parse(text=f))))
a=1:5
b=1:5
f = "(a-b)*a/b"
result = apply(expand.grid(a,b),1,\(x) foo(f)(x[1],x[2]))

Output:

 [1]  0.0000000 -0.5000000 -0.6666667 -0.7500000 -0.8000000  2.0000000  0.0000000
 [8] -0.6666667 -1.0000000 -1.2000000  6.0000000  1.5000000  0.0000000 -0.7500000
[15] -1.2000000 12.0000000  4.0000000  1.3333333  0.0000000 -0.8000000 20.0000000
[22]  7.5000000  3.3333333  1.2500000  0.0000000

CodePudding user response:

Using alist and as.function, and outer instead of double for loop.

foo1 <- function(fo=y ~ a - b, a=1:30, b=1:30) {
  f <- as.function(c(alist(b=, a=), fo[[3]]))
  outer(b, a, f) |> as.vector()
}

## test
result <- foo()  ## G. Grothendieck's
result1 <- foo1()

stopifnot(all.equal(result, result1))
  • Related