Evaluate expression given as a string

前端 未结 7 1911
小蘑菇
小蘑菇 2020-11-21 23:41

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         


        
相关标签:
7条回答
  • 2020-11-22 00:00

    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"
    
    0 讨论(0)
  • 2020-11-22 00:01

    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
    
    0 讨论(0)
  • 2020-11-22 00:10

    Nowadays you can also use lazy_eval function from lazyeval package.

    > lazyeval::lazy_eval("5+5")
    [1] 10
    
    0 讨论(0)
  • 2020-11-22 00:14

    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"))
    
    0 讨论(0)
  • 2020-11-22 00:17

    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.

    0 讨论(0)
  • 2020-11-22 00:18

    Similarly using rlang:

    eval(parse_expr("5+5"))
    
    0 讨论(0)
提交回复
热议问题