Evaluate expression given as a string

REvalR Faq

R Problem Overview


I'm curious to know if R can use its eval() function to perform calculations provided by e.g. a string.

This is a common case:

eval("5+5")

However, instead of 10 I get:

[1] "5+5"

Any solution?

R Solutions


Solution 1 - R

The eval() function evaluates an expression, but "5+5" is a string, not an expression. Use parse() with text=<string> to change the string into an expression:

> eval(parse(text="5+5"))
[1] 10
> class("5+5")
[1] "character"
> class(parse(text="5+5"))
[1] "expression"

Calling eval() invokes many behaviours, some are not immediately obvious:

> class(eval(parse(text="5+5")))
[1] "numeric"
> class(eval(parse(text="gray")))
[1] "function"
> class(eval(parse(text="blue")))
Error in eval(expr, envir, enclos) : object 'blue' not found

See also tryCatch.

Solution 2 - R

You can use the parse() function to convert the characters into an expression. You need to specify that the input is text, because parse expects a file by default:

eval(parse(text="5+5"))

Solution 3 - R

Sorry but I don't understand why too many people even think a string was something that could be evaluated. You must change your mindset, really. Forget all connections between strings on one side and expressions, calls, evaluation on the other side.

The (possibly) only connection is via parse(text = ....) and all good R programmers should know that this is rarely an efficient or safe means to construct expressions (or calls). Rather learn more about substitute(), quote(), and possibly the power of using do.call(substitute, ......).

fortunes::fortune("answer is parse")
# If the answer is parse() you should usually rethink the question.
#    -- Thomas Lumley
#       R-help (February 2005)

Dec.2017: Ok, here is an example (in comments, there's no nice formatting):

q5 <- quote(5+5)
str(q5)
# language 5 + 5

e5 <- expression(5+5)
str(e5)
# expression(5 + 5)

and if you get more experienced you'll learn that q5 is a "call" whereas e5 is an "expression", and even that e5[[1]] is identical to q5:

identical(q5, e5[[1]])
# [1] TRUE

Solution 4 - R

Alternatively, you can use evals from my pander package to capture output and all warnings, errors and other messages along with the raw results:

> pander::evals("5+5")
[[1]]
$src
[1] "5 + 5"

$result
[1] 10

$output
[1] "[1] 10"

$type
[1] "numeric"

$msg
$msg$messages
NULL

$msg$warnings
NULL

$msg$errors
NULL


$stdout
NULL

attr(,"class")
[1] "evals"

Solution 5 - R

Nowadays you can also use lazy_eval function from lazyeval package.

> lazyeval::lazy_eval("5+5")
[1] 10

Solution 6 - R

Not sure why no one has mentioned two Base R functions specifically to do this: str2lang() and str2expression(). These are variants of parse(), but seem to return the expression more cleanly:

eval(str2lang("5+5"))

# > 10
  
eval(str2expression("5+5"))

# > 10

Also want to push back against the posters saying that anyone trying to do this is wrong. I'm reading in R expressions stored as text in a file and trying to evaluate them. These functions are perfect for this use case.

Solution 7 - R

Similarly using rlang:

eval(parse_expr("5+5"))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFederico GiorgiView Question on Stackoverflow
Solution 1 - RHarlanView Answer on Stackoverflow
Solution 2 - RShaneView Answer on Stackoverflow
Solution 3 - RMartin MächlerView Answer on Stackoverflow
Solution 4 - RdaroczigView Answer on Stackoverflow
Solution 5 - RPaweł Kozielski-RomaneczkoView Answer on Stackoverflow
Solution 6 - RDavid J. BosakView Answer on Stackoverflow
Solution 7 - Rc1au61o_HHView Answer on Stackoverflow