4

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?

1
  • The trickiest part would seem to be determining the parameter order for your function. Are you sure you really need a function? How will you call the function if you aren't sure what parameters it takes. There may be better strategies like just evaluating an expression rather than creating a function but it's not clear exactly what your requirements are. Commented Dec 3, 2021 at 19:19

1 Answer 1

4

1) body 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) as.function 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) match.funfn gsubfn also has match.funfn that is like match.fun in R except it also translates arguments passed as formulas to functions. e.g.

library(gsubfn)

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

4) fn$ gsubfn also provides fn which when prefixed to an arbitrary function will interpret formulas as functions. See the help file ?fn for details. Note that sapply was not specially written for this but it works anyways.

library(gsubfn)

fn$sapply(1:3, ~ x^2)
## [1] 1 4 9
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.