Maximizing mathematical function which is saved as character string

59 views Asked by At

I have the following problem: I'm writing a function which first constructs a long character string which stands for a mathematical function, e.g. "1/(1+exp(-x1+4x3))". I now want to maximize this function, but unfortunately I cannot do so because the mathematical function is only saved as a character string and not as an R-function. How can I solve this problem? Thanks in advance!

2

There are 2 answers

1
G. Grothendieck On BEST ANSWER

If we know what the arguments are ahead of time then (1) would be preferred as it is simpler (4 lines of code) but if we don't then (2) covers generating them as well (8 lines of code).

1) dynamic body This will convert the string s into a function f2 of 2 arguments which we can call from f1 having one argument as required by optim:

s <- "1/(1+exp(-x1+4*x3))" # test input

f1 <- function(x) do.call("f2", as.list(x))  # f1 calls f2

f2 <- function(x1, x3) {}
body(f2) <- parse(text = s)

optim(c(0, 0), f1, control = list(fnscale = -1))

2) dynamic body + dynamic args In the above we dynamically created the body from the string assuming we knew the arguments but if you want to dynamically create both the body and arguments then try this. Here f2 no longer necessarily has 2 arguments but has nv arguments and what they are is derived from the input s.

s <- "1/(1+exp(-x1+4*x3))" # test input - same as above

f1 <- function(x) do.call("f2", as.list(x))  # function on one argument - same as above

# f2 has nv arguments
f2 <- function() {}
p <- parse(text = s)
v <- all.vars(p) # character string of variable names used for arguments
nv <- length(v)
formals(f2) <- setNames(rep(alist(x=), nv), v)
body(f2) <- p

optim(numeric(nv), f1, control = list(fnscale = -1)) # first arg different from (1)
0
Roland On

I'm writing a function which first constructs a long character string which stands for a mathematical function

Don't do that. I'm sure there is a better approach.

because the mathematical function is only saved as a character string and not as an R-function

You'd need to parse the string (after making it valid R syntax):

expr <- parse(text = gsub("((?<=\\d)[[:alpha:]])", "\\*\\1","1/(1+exp(-x1+4x3))", perl = TRUE))

Then you can use this expression to "find the maximum" with whatever method you'd like to use.

However, as fortune 106 says:

If the answer is parse() you should usually rethink the question.