我很想知道R是否可以使用其eval()
函数来执行例如一个字符串。
这是一个常见的案例:
eval("5+5")
但是,我得到的不是10:
[1] "5+5"
任何解决方案?
答案 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"))