我很好奇R是否可以使用它的eval()函数来执行由字符串等提供的计算。
这是一个常见的情况:
eval("5+5")
然而,我得到的不是10:
[1] "5+5"
有解决方案吗?
我很好奇R是否可以使用它的eval()函数来执行由字符串等提供的计算。
这是一个常见的情况:
eval("5+5")
然而,我得到的不是10:
[1] "5+5"
有解决方案吗?
当前回答
抱歉,但我不明白为什么这么多人甚至认为字符串是可以计算的东西。你必须改变你的心态,真的。 忘掉一边的字符串和另一边的表达式、调用、求值之间的所有连接。
(可能)唯一的连接是通过解析(text = ....),所有优秀的R程序员都应该知道,这很少是一种有效或安全的构造表达式(或调用)的方法。而是更多地了解substitute()、quote(),以及可能使用do的功能。调用(替代 , ......).
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是一个“调用”,而e5是一个“表达式”,甚至e5[[1]]与q5是相同的:
identical(q5, e5[[1]])
# [1] TRUE
其他回答
可以使用parse()函数将字符转换为表达式。你需要指定输入为文本,因为parse默认期望一个文件:
eval(parse(text="5+5"))
eval()函数计算一个表达式,但"5+5"是一个字符串,而不是表达式。使用parse() with 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。
类似地使用rlang:
eval(parse_expr("5+5"))
或者,你可以使用我的pander包中的eval来捕获输出和所有警告、错误和其他消息以及原始结果:
> 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"
不知道为什么没有人提到两个Base R函数专门做这件事:str2lang()和str2expression()。这些是parse()的变体,但似乎返回的表达式更清晰:
eval(str2lang("5+5"))
# > 10
eval(str2expression("5+5"))
# > 10
也想反驳那些海报上说的任何试图这样做的人都是错误的。我在R中读取作为文本存储在文件中的表达式,并试图计算它们。这些函数非常适合这个用例。