Home Articles

评估以字符串形式给出的表达式

Asked
Viewed 1899 times
235

我很想知道R是否可以使用它的 eval() 函数来执行例如由一个字符串 .

这是一个常见的情况:

eval("5+5")

但是,而不是10我得到:

[1] "5+5"

有解决方案吗

5 Answers

  • 356

    eval() 函数计算表达式,但 "5+5" 是字符串,而不是表达式 . 使用 parse()text=<string> 将字符串更改为表达式:

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

    调用 eval() 会调用许多行为,有些行为不是很明显:

    > 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
    

    另见tryCatch .

  • 83

    您可以使用 parse() 函数将字符转换为表达式 . 您需要指定输入是文本,因为默认情况下parse需要一个文件:

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

    现在你也可以使用 lazyeval 包中的 lazy_eval 函数 .

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

    抱歉,但我不明白为什么有太多人甚至认为字符串是可以评估的东西 . 你必须改变你的心态 . 忘记一边的字符串和表达式,调用,另一边的评估之间的所有连接 .

    (可能)唯一的连接是通过 parse(text = ....) 并且所有优秀的R程序员都应该知道这很少是构造表达式(或调用)的有效或安全的方法 . 而是要了解有关 substitute()quote() 的更多信息,以及使用 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:好的,这是一个例子(在评论中,没有很好的格式):

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

    如果你有更多经验,你会得知 q5"call"e5"expression" ,甚至 e5[[1]]q5 相同:

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

    或者,您可以使用 pander 包中的 evals 捕获输出以及所有警告,错误和其他消息以及原始结果:

    > 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"
    

Related