Вычислить выражение, заданное в виде строки

StackOverflow https://stackoverflow.com/questions/1743698

  •  20-09-2019
  •  | 
  •  

Вопрос

Мне любопытно узнать, может ли 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

Смотрите также Пробный улов.

Другие советы

Вы можете использовать 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)

Декабрь 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"))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top