321

我很想知道 R 是否可以使用它的eval()函数来执行由例如字符串提供的计算。

这是一个常见的情况:

eval("5+5")

但是,我得到的不是 10:

[1] "5+5"

有什么解决办法吗?

4

7 回答 7

467

eval()函数计算一个表达式,但"5+5"它是一个字符串,而不是一个表达式。使用parse()withtext=<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

于 2009-11-16T17:55:29.023 回答
109

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

eval(parse(text="5+5"))
于 2009-11-16T17:47:13.890 回答
58

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

(可能)唯一的连接是 via 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)

2017 年 12 月:好的,这是一个示例(在评论中,没有很好的格式):

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

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

如果您有更多经验,您会知道这q5是 a "call"whilee5是 an "expression",甚至e5[[1]]与 相同q5

identical(q5, e5[[1]])
# [1] TRUE
于 2016-10-20T20:38:47.103 回答
19

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

> 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"
于 2015-10-12T03:46:06.783 回答
19

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

> lazyeval::lazy_eval("5+5")
[1] 10
于 2018-02-04T00:40:23.770 回答
16

不知道为什么没有人专门提到两个 Base R 函数来做到这一点: str2lang()str2expression(). 这些是 的变体parse(),但似乎更干净地返回表达式:

eval(str2lang("5+5"))

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

# > 10

还想反击海报说任何试图这样做的人都是错误的。我正在读取作为文本存储在文件中的 R 表达式并尝试评估它们。这些功能非常适合这个用例。

于 2020-09-20T00:47:58.087 回答
7

同样使用rlang

eval(parse_expr("5+5"))
于 2019-04-13T00:42:09.883 回答