329 Stimmen

Ausdruck in Form einer Zeichenkette auswerten

Ich bin neugierig zu wissen, ob R seine eval() Funktion, um Berechnungen durchzuführen, die z. B. durch eine Zeichenkette bereitgestellt werden.

Dies ist ein häufiger Fall:

eval("5+5")

Anstelle von 10 erhalte ich jedoch:

[1] "5+5"

Gibt es eine Lösung?

474voto

Harlan Punkte 18013

En eval() Funktion wertet einen Ausdruck aus, aber "5+5" ist eine Zeichenkette, kein Ausdruck. Verwenden Sie parse() con text=<string> um die Zeichenkette in einen Ausdruck zu verwandeln:

> eval(parse(text="5+5"))
[1] 10
> class("5+5")
[1] "character"
> class(parse(text="5+5"))
[1] "expression"

Aufruf von eval() ruft viele Verhaltensweisen hervor, von denen einige nicht sofort offensichtlich sind:

> 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

Siehe auch tryCatch .

111voto

Shane Punkte 95376

Sie können die parse() Funktion, um die Zeichen in einen Ausdruck umzuwandeln. Sie müssen angeben, dass die Eingabe ein Text ist, da parse standardmäßig eine Datei erwartet:

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

60voto

Martin Mächler Punkte 4344

Es tut mir leid, aber ich verstehe nicht, warum zu viele Leute glauben, eine Zeichenkette sei etwas, das ausgewertet werden kann. Ihr müsst eure Denkweise ändern, wirklich. Vergessen Sie alle Verbindungen zwischen Strings auf der einen Seite und Ausdrücken, Aufrufen und Auswertungen auf der anderen Seite.

Die (möglicherweise) einzige Verbindung erfolgt über parse(text = ....) und alle guten R-Programmierer sollten wissen, dass dies selten ein effizientes oder sicheres Mittel ist, um Ausdrücke (oder Aufrufe) zu konstruieren. Lernen Sie lieber mehr über substitute() , quote() und möglicherweise die Macht der Verwendung von 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)

Dez.2017: Ok, hier ist ein Beispiel (in den Kommentaren, es gibt keine schöne Formatierung):

q5 <- quote(5+5)
str(q5)
# language 5 + 5

e5 <- expression(5+5)
str(e5)
# expression(5 + 5)

und wenn Sie mehr Erfahrung haben, werden Sie lernen, dass q5 ist eine "call" während e5 ist ein "expression" und sogar das e5[[1]] ist identisch mit q5 :

identical(q5, e5[[1]])
# [1] TRUE

19voto

daroczig Punkte 27061

Alternativ können Sie auch evals von meinem pander Paket, um die Ausgabe und alle Warnungen, Fehler und sonstigen Meldungen zusammen mit den Rohergebnissen zu erfassen:

> 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"

19voto

Heutzutage können Sie auch lazy_eval Funktion von lazyeval Paket.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X