Ich bin gespannt, ob R seine eval()
Funktion verwenden kann, um Berechnungen durchzuführen, die beispielsweise von einer Zeichenfolge bereitgestellt werden.
Dies ist ein häufiger Fall:
eval("5+5")
Anstelle von 10 bekomme ich jedoch:
[1] "5+5"
Irgendeine Lösung?
string
? Die Antwort von Martin Mächler sollte viel mehr Stimmen verdienen.eval(parse(text = *))
gefälschte Lösungen befürworten .QQ = c('11','12','13','21','22','23')
dh QQ = c (..., 'ij', ..), wobei i, j in einem Bereich variieren, der von Lauf zu Lauf variieren kann. Für dieses und ähnliche Beispiele kann ich das Skript als schreibenpaste( "QQ = c('", paste(rep(1:2,each=3),1:3, sep="", collapse="','"), "')",sep="")
, und die Optioneval(parse(text=...))
erstellt den Vektor QQ in der Arbeitsumgebung gemäß dem Skript. Was wäre der richtige R-Codierer, um dies zu tun, wenn nicht mit "text = ..."?Antworten:
Die
eval()
Funktion wertet einen Ausdruck aus,"5+5"
ist jedoch eine Zeichenfolge und kein Ausdruck. Verwenden Sieparse()
mittext=<string>
, um die Zeichenfolge in einen Ausdruck zu ändern:Das Aufrufen
eval()
ruft viele Verhaltensweisen hervor, einige sind nicht sofort offensichtlich:Siehe auch tryCatch .
quelle
quote()
, diebquote()
mit oder den komplexeren Tools desrlang
Pakets erstellt wurden.rlang
aber das Nächste, was ich gefunden habe, war,parse_expr
welche Anrufeparse_exprs
das Gleiche sind wie das Verwendenparse
und Einwickeln,eval
was anscheinend dasselbe ist wie hier. Ich bin mir nicht sicher, welchen Vorteil die Verwendung hätterlang
.rlang
würden Sie direkt mit Ausdrücken arbeiten, nicht mit Zeichenfolgen. Kein Analyseschritt erforderlich. Es hat zwei Vorteile. 1. Ausdrucksmanipulationen erzeugen immer gültige Ausdrücke. String-Manipulationen erzeugen nur gültige Strings. Sie werden nicht wissen, ob es sich um gültige Ausdrücke handelt, bis Sie sie analysieren. 2. Es gibt kein Äquivalent zursubstitute()
Funktionsklasse in der String-Welt, was Ihre Fähigkeit, Funktionsaufrufe zu manipulieren, stark einschränkt. Betrachten Sie diesen glm-Wrapper . Wie würde ein String-Äquivalent aussehen?Mit der
parse()
Funktion können Sie die Zeichen in einen Ausdruck konvertieren. Sie müssen angeben, dass die Eingabe Text ist, da parse standardmäßig eine Datei erwartet:quelle
parse
ständig! github.com/wch/r-source/…Tut mir leid, aber ich verstehe nicht, warum zu viele Leute glauben, dass eine Zeichenfolge bewertet werden kann. Sie müssen Ihre Einstellung wirklich ändern. Vergessen Sie alle Verbindungen zwischen Zeichenfolgen auf der einen Seite und Ausdrücken, Aufrufen und Auswertungen auf der anderen Seite.
Die (möglicherweise) einzige Verbindung ist ü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. Vielmehr erfahren Sie mehr übersubstitute()
,quote()
und möglicherweise die Macht der Verwendungdo.call(substitute, ......)
.Dez.2017: Ok, hier ist ein Beispiel (in Kommentaren gibt es keine nette Formatierung):
und wenn Sie mehr Erfahrung haben, werden Sie lernen, dass dies
q5
eine"call"
Weilee5
ist"expression"
, und selbst dase5[[1]]
ist identisch mitq5
:quelle
q5 <- quote(5+5)
oben steht der Ausdruck (eigentlich der "Aufruf")5+5
und es ist ein R-Objekt, aber keine Zeichenfolge. Sie können es jederzeit auswerten. Nochmals: using, quote (), replace (), ... stattdessen erstellt parse Aufrufe oder Ausdrücke direkt und effizienter als via parse (text =.). Die Verwendungeval()
ist in Ordnung, die Verwendungparse(text=*)
ist fehleranfällig und manchmal im Vergleich zu Konstruktionsaufrufen und deren Manipulation recht ineffizient. @Nick S: Es isteval(q5)
odereval(e5)
in unserem laufenden Beispieleval(.)
Sie ihn auf. Mein Punkt war, dass die Leute nicht verwenden solltenparse(text=.)
, sondernquote(.)
usw., um den Anruf zu konstruieren, der spätereval()
bearbeitet wird.eval(quote())
funktioniert in einigen Fällen, schlägt aber in einigen Fällen fehl, in deneneval(parse())
es gut funktionieren würde.Alternativ können Sie
evals
aus meinempander
Paket die Ausgabe und alle Warnungen, Fehler und anderen Meldungen zusammen mit den Rohergebnissen erfassen:quelle
evaluate::evaluate
tatsächliche Zurückgeben des Ergebnisobjekts übrig bleibt ; Damit ist Ihre Funktion für den Anruf über mclapply geeignet. Ich hoffe, dass diese Funktion erhalten bleibt!rapport
Pakets geschrieben und wurde seitdem aktiv gepflegt, da sie neben einigen anderen Projekten auch in unserem rapporter.net- Dienst stark genutzt wird während :) Ich bin froh, dass Sie es nützlich finden, danke für Ihr freundliches Feedback.Heutzutage können Sie auch die
lazy_eval
Funktion aus demlazyeval
Paket verwenden.quelle
Ähnlich mit
rlang
:quelle
rlang
Antwort, aber was ist, wenn überhaupt, der Vorteil dieser gegenüber Basisalternativen? Tatsächlich zeigt eine genaue Untersuchung des verwendeten Codes, dass er tatsächlich verwendet wird,eval(parse(....))
was ich vermeiden wollte.