Вычислить выражение, заданное в виде строки
мне любопытно узнать, может ли R использовать его eval() функция для выполнения вычислений, предоставляемых, например, строкой.
это обычный случай:
eval("5+5")
однако вместо 10 я получаю:
[1] "5+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() функции для преобразования символов в выражении. Вам нужно указать, что ввод является текстом, потому что parse ожидает файл по умолчанию:
eval(parse(text="5+5"))
Извините, но я не понимаю, почему слишком много людей даже думают, что строка была чем-то, что можно оценить. Вы должны изменить свое мышление. Забудьте все связи между строками с одной стороны и выражениями, вызовами, оценкой с другой стороны.
(возможно) только соединение через 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
кроме того, вы можете использовать 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"