Bewerten Ausdruck als String gegeben
Frage
Ich bin neugierig, ob R seine eval()
Funktion können Berechnungen von z vorgesehen auszuführen ein String.
Dies ist ein häufiger Fall:
eval("5+5")
Doch statt 10 erhalte ich:
[1] "5+5"
Jede Lösung?
Lösung
Die eval()
Funktion wertet einen Ausdruck, aber "5+5"
ist ein String, kein Ausdruck. Verwenden parse()
mit text=<string>
die Zeichenfolge in einen Ausdruck zu ändern:
> eval(parse(text="5+5"))
[1] 10
> class("5+5")
[1] "character"
> class(parse(text="5+5"))
[1] "expression"
Der Aufruf eval()
ruft viele Verhaltensweisen, einige sind nicht sofort offensichtlich:
> 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 .
Andere Tipps
Sie können die parse()
Funktion verwenden, um die Zeichen in einen Ausdruck zu konvertieren. Sie müssen angeben, dass die Eingabe von Text, weil Parse eine Datei standardmäßig erwartet:
eval(parse(text="5+5"))
Sorry, aber ich verstehe nicht, warum zu viele Leute glauben sogar, eine Zeichenkette, die etwas war, das ausgewertet werden konnte. Sie müssen Ihre Einstellung ändern, wirklich. Vergessen Sie alle Verbindungen zwischen Saiten auf der einen Seite und Ausdrücke, Anrufe, die Bewertung auf der anderen Seite.
Der (möglicherweise) nur Anschluss erfolgt über parse(text = ....)
und alle gute R Programmierer sollen wissen, dass dies selten ein effizientes oder sicheres Mittel zu konstruieren Ausdrücke (oder Anrufen). Vielmehr erfahren Sie mehr über substitute()
, quote()
und möglicherweise die Macht der do.call(substitute, ......)
verwendet wird.
fortunes::fortune("answer is parse")
# If the answer is parse() you should usually rethink the question.
# -- Thomas Lumley
# R-help (February 2005)
Dec.2017: Ok, hier ist ein Beispiel (in den Kommentaren gibt es 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 erhalten erfahren Sie, dass q5
lernen werden ist eine "call"
während e5
ein "expression"
ist, und auch das e5[[1]]
ist identisch mit q5
:
identical(q5, e5[[1]])
# [1] TRUE
Alternativ können Sie evals
von meinem pander
Paket-Capture-Ausgang und alle Warnungen, Fehler und andere Nachrichten zusammen mit den Rohergebnisse verwenden:
> 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"
Heutzutage kann man auch lazy_eval
Funktion von lazyeval
Paket verwenden.
> lazyeval::lazy_eval("5+5")
[1] 10
In ähnlichem rlang
mit:
eval(parse_expr("5+5"))