我很想知道 R 是否可以使用它的eval()
函数来执行由例如字符串提供的计算。
这是一个常见的情况:
eval("5+5")
但是,我得到的不是 10:
[1] "5+5"
有什么解决办法吗?
该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。
您可以使用该parse()
函数将字符转换为表达式。您需要指定输入是文本,因为 parse 默认需要一个文件:
eval(parse(text="5+5"))
抱歉,但我不明白为什么有太多人甚至认为字符串是可以评估的。你必须改变你的心态,真的。忘记一侧的字符串和另一侧的表达式、调用、评估之间的所有连接。
(可能)唯一的连接是 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
或者,您可以使用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
不知道为什么没有人专门提到两个 Base R 函数来做到这一点: str2lang()
和str2expression()
. 这些是 的变体parse()
,但似乎更干净地返回表达式:
eval(str2lang("5+5"))
# > 10
eval(str2expression("5+5"))
# > 10
还想反击海报说任何试图这样做的人都是错误的。我正在读取作为文本存储在文件中的 R 表达式并尝试评估它们。这些功能非常适合这个用例。
同样使用rlang
:
eval(parse_expr("5+5"))