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

时间:2009-11-16 17:39:32

标签: r eval r-faq

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

这是一个常见的案例:

eval("5+5")

但是,我得到的不是10:

[1] "5+5"

任何解决方案?

7 个答案:

答案 0 :(得分:367)

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

答案 1 :(得分:86)

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

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

答案 2 :(得分:40)

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

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

答案 3 :(得分:16)

或者,您可以使用我的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"

答案 4 :(得分:11)

现在您还可以使用lazy_eval包中的lazyeval功能。

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

答案 5 :(得分:4)

不确定为什么没有人提到两个专门用于执行此操作的Base R函数:str2lang()str2expression()。这些是parse()的变体,但似乎更清晰地返回了表达式:

eval(str2lang("5+5"))

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

# > 10

也想推翻海报,说任何试图这样做的人都是错误的。我正在读取以文本形式存储在文件中的R表达式,并尝试对其求值。这些功能非常适合此用例。

答案 6 :(得分:1)

类似地使用rlang

eval(parse_expr("5+5"))