Search code examples
rstringparsingexpressioneval

R: evaluate comma-separated string as an expression


I have a comma-separated string that I want to plug into a function as a comma-separated expression. Specifically, there are various functions that take ... as a parameter, and I want to have a method for converting comma-separated strings into a list of comma-separated parameters that can be 'injected' into the ... parameter in a function call. I tried using parse and eval as hinted at on this page, but I am still failing to get my function to work.

Below you see a reproducible example of what I am trying to do.

This works just fine

a <- 1
b <- 2
sum(a, b)

If a and b are encoded in a string, I can't get them to evaluate in the sum function

This fails because myString is of character class, and the function tries to evaluate it as is instead of parsing it into components a and b.

myString <- 'a, b'
sum(myString)

Trying to use parse and eval also fails

These give an error about unexpected commas.

sum(parse(text = myString))
sum(eval(parse(text = mystring)))

Output:

Error in parse(text = myString) : <text>:1:2: unexpected ','
1: a,
     ^

What function or set of functions (fxn) must I use on myString so that sum will correctly evaluate?

My desired solution will take the following format, where fxn are the functions that must be used on myString before the sum function:

# Acceptable solution format
sum(fxn(myString))

# Alternatively by piping
myString %>%
    fxn %>%
    sum

Update:

The solution must be generalizable enough to handle if there are more than just two values encoded in myString. For example, the solution must also work if:

c <- 3
d <- 4
e <- 5
myString2 <- 'c, d, e'

# This:
sum(fxn(myString2))

# Must yield `12`

Furthermore, the result should be generalizable enough to work for a variety of functions that take ... as a parameter, not just sum. I selected sum for the example for simplicity. However, below is another example of desired behavior:

f <- 6
g <- 7
myString3 <- 'f, g'

# This:
prod(fxn(myString3))

# Must yield `42`

Solution

  • I think the solution is to use strsplit, then get() each value by sapply().

    a <- 1
    b <- 2
    c <- 3
    d <- 4
    myString <- 'a, b, c, d'
    
    fxn <- function(myString) 
    {
      values <- unlist(strsplit(myString, split = ", "))
      sapply(values, function(x){get(x)})
    }
    sum(fxn(myString))
    
    [1] 10