web-dev-qa-db-ja.com

文字列として与えられた式を評価する

Rがeval()関数を使用して、たとえば文字列。

これは一般的なケースです。

eval("5+5")

ただし、10の代わりに次のようになります。

[1] "5+5"

解決策はありますか?

251
Federico Giorgi

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 もご覧ください。

369
Harlan

parse()関数を使用して、文字を式に変換できます。 parseはデフォルトでファイルを想定しているため、入力がテキストであることを指定する必要があります。

eval(parse(text="5+5"))
86
Shane

申し訳ありませんが、なぜ文字列が評価できるものであると考える人が多すぎるのか理解できません。本当にあなたの考え方を変えなければなりません。一方の文字列と他方の式、呼び出し、評価の間のすべての接続を忘れてください。

(おそらく)唯一の接続は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月:OK、ここに例があります(コメントでは、ニースの書式設定はありません):

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
40
Martin Mächler

または、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"
16
daroczig

最近では、lazyevalパッケージのlazy_eval関数も使用できます。

> lazyeval::lazy_eval("5+5")
[1] 10

同様にrlangを使用:

eval(parse_expr("5+5"))
1
c1au61o_HH