Is it possible to assign a string containing variable names to a variable in R?
For example imagine I have the string "log(p_n) log((1 - p_n)) log(p_n * p_b) log(p_n * (1 - p_b)) log((1 - p_n) * p_g)"
. I'd like to make this function:
formula_function = function(p_n, p_b, p_g){
x <- log(p_n) log((1 - p_n)) log(p_n * p_b) log(p_n * (1 - p_b)) log((1 - p_n) * p_g)
return(x)
}
I have a function which generates the formula strings and I'm just copy-pasting them by hand at the moment, is there a more 'program-y' way of doing it?
CodePudding user response:
1) Assuming you know the parameters:
x <- "log(p_n) log((1 - p_n)) log(p_n * p_b) log(p_n * (1 - p_b)) log((1 - p_n) * p_g)"
f <- function(p_n, p_b, p_g) {}
body(f) <- parse(text = x)
f
## function (p_n, p_b, p_g)
## log(p_n) log((1 - p_n)) log(p_n * p_b) log(p_n * (1 - p_b))
## log((1 - p_n) * p_g)
2) The gsubfn package has a function for converting formulas to functions. The order of the formal arguments will be in the order encountered in x or you can specify the order. Convert the string to a formula using reformulate and then use as.function.
library(gsubfn)
# args are in order encountered
f <- as.function(reformulate(x))
f
## function (p_n, p_b, p_g)
## log(p_n) log((1 - p_n)) log(p_n * p_b) log(p_n * (1 - p_b))
## log((1 - p_n) * p_g)
# specify order of args
f <- as.function(reformulate(x, "p_n p_g p_b"))
f
## function (p_n, p_g, p_b)
## log(p_n) log((1 - p_n)) log(p_n * p_b) log(p_n * (1 - p_b))
## log((1 - p_n) * p_g)
3) gsubfn also has match.funfn that is like match.fun in R except it also translates arguments passed as formulas to functions. e.g.
myfun <- function(a, b, c, fun) {
f <- match.funfn(fun)
f(a, b, c)
}
myfun(0.1, 0.1, 0.1, reformulate(x, "p_n p_g p_b"))
## [1] -11.82901