题
我想知道如果R可以使用其eval()
函数来执行通过例如提供计算一个字符串。
这是一个常见的情况:
eval("5+5")
但是,而不是10获取:
[1] "5+5"
任何溶液?
解决方案
在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 。
其他提示
可以使用parse()
函数可以将字符转换成的表达式。您需要指定输入是文本,因为解析在默认情况下需要一个文件:
eval(parse(text="5+5"))
很抱歉,但我不明白为什么有太多人甚至认为一个字符串,是个可以进行评估。你必须改变你的心态,真的。 忘记在另一侧上的一个侧字符串和表达式,来电,评价之间的所有连接。
在(可能)仅连接是经由parse(text = ....)
和所有良好ř程序员应该知道,这是很少以构建表达(或呼叫)的有效或安全手段。而进一步了解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
可替换地,可以使用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"
现在还可以使用lazy_eval
函数从lazyeval
包。
> lazyeval::lazy_eval("5+5")
[1] 10
类似地使用rlang
:
eval(parse_expr("5+5"))
不隶属于 StackOverflow