Ich hoffe zu wissen, warum dies message()
eine bessere Wahl ist als print()
beim Drucken von Diagnosemeldungen.
Zum Beispiel ist die print()
Funktion eine bessere Wahl, um ein R-Objekt zu drucken, wie z. B. 'iris'
, message()
wenn sie Zeichenfolgen verketten möchte, z . B. message("a", "b")
kürzer als print(paste0("a", "b"))
.
Ich denke jedoch, dass es mehr Unterschiede gibt als die oben aufgeführten einfachen. Ich habe die Dokumentation für beide Methoden gelesen
- http://stat.ethz.ch/R-manual/R-devel/library/base/html/message.html ,
- http://stat.ethz.ch/R-manual/R-devel/library/base/html/print.html
aber es scheint, dass sie nicht so informativ sind, wie ich auf meine Frage gehofft hatte.
Ich würde mich freuen, wenn uns jemand mitteilen würde, in welchem Fall message()
besser ist als print()
und warum.
message()
signalisiere aber auch eine "Nachricht", diesuppressMessages()
erfasst wird.suppressMessages()
Unterdrücken Sie keine reine stderr-Ausgabe, z. B.suppressMessages(cat("hello\n", file=stderr()))
zeigt sie immer nochhello
in der Konsole an.stop
,warning
,message
alle Signalbedingungen, das ist , was sie fangen / Unterdrückungs-fähig machttryCatch(message("hello"), message=force)
;cat(file=stderr())
ist schlecht (und ineffektiv, wie Ihr Beispiel zeigt!), wenn die Absicht besteht, einen diagnostischen Zustand zu signalisieren.Antworten:
TL; DR
Sie sollten verwenden,
cat()
wenn Sie dieprint.*()
Funktionen für S3-Objekte erstellen. Für alles andere sollten Sie verwenden, esmessage()
sei denn, der Status des Programms ist problematisch. zB schlechte Fehler, der erzielbare ist gibtwarning()
vs. Show stoppen Fehler Anwendungenstop()
.Tor
Das Ziel dieses Beitrags ist es, Feedback zu den verschiedenen Ausgabeoptionen zu geben, auf die ein Paketentwickler Zugriff hat, und wie die Ausgabe strukturiert werden sollte, die möglicherweise auf einem neuen Objekt oder auf Zeichenfolgen basiert.
R Ausgabeübersicht
Die traditionellen Ausgabefunktionen sind:
print()
cat()
message()
warning()
stop()
Jetzt senden die ersten beiden Funktionen (
print()
undcat()
) ihre Ausgabe anstdout
oder Standardausgabe. Die letzten drei Funktionen (message()
,warning()
, undstop()
) senden ihre Ausgabe anstderr
oder den Standardfehler. Das heißt, die Ergebnisausgabe eines Befehls wielm()
wird an eine Datei gesendet, und die Fehlerausgabe - falls vorhanden - wird an eine vollständig separate Datei gesendet. Dies ist besonders wichtig für die Benutzererfahrung, da die Ausgabe der Ergebnisse in Protokolldateien durch die Diagnose nicht überladen wird und Fehler zur schnellen Suche verfügbar sind.Entwerfen für Benutzer und externe Pakete
Das Obige ist nun eher in einer E / A- Denkweise und nicht unbedingt in einem benutzerbezogenen Frameset dargestellt. Lassen Sie uns also im Kontext eines alltäglichen R-Benutzers eine gewisse Motivation dafür liefern. Insbesondere durch die Verwendung von 3-5 oder der
stderr
Funktionen kann deren Ausgabe unterdrückt werden, ohne übersink()
oder mit dem Konsolentext zu bastelncapture.output()
. Die Unterdrückung kommt normalerweise in Form vonsuppressWarnings()
,suppressMessages()
,suppressPackageStartupMessages()
und so weiter. Daher werden Benutzer nur mit ergebnisorientierten Ausgaben konfrontiert. Dies ist besonders wichtig, wenn Sie Benutzern die Flexibilität geben möchten, die textbasierte Ausgabe zu deaktivieren , wenn Sie dynamische Dokumente über Knitr , Rmarkdown oder Sweave erstellen .Insbesondere
knitr
bietet chunk Optionen wieerror = F
,message = F
, undwarning = F
. Dies ermöglicht die Reduzierung von Text, der einem Befehl im Dokument beigefügt ist. Darüber hinaus wird verhindert, dass dieresults = "hide"
Option verwendet werden muss, mit der alle Ausgaben deaktiviert werden.Besonderheiten der Ausgabe
drucken()
Als erstes haben wir einen Oldie, aber einen Goodie
print()
. Diese Funktion weist einige schwerwiegende Einschränkungen auf. Eine davon ist das Fehlen einer eingebetteten Verkettung von Begriffen. Das zweite und wahrscheinlich schwerwiegendere Problem ist die Tatsache, dass vor jeder Ausgabe[x]
Zitate über den tatsächlichen Inhalt stehen. Dasx
bezieht sich in diesem Fall auf die zu druckende Elementnummer. Dies ist hilfreich für Debugging-Zwecke, hat aber darüber hinaus keinen Zweck.z.B
print("Hello!") [1] "Hello!"
Für die Verkettung verlassen wir uns auf die
paste()
Funktion, die synchron arbeitet mitprint()
:print(paste("Hello","World!")) [1] "Hello World!"
Alternativ kann man die
paste0(...)
Funktion anstelle von verwendenpaste(...)
, um die Standardverwendung von a spacezwischen Elementen zu vermeiden, die durchpaste()
densep = " "
Parameter von ' gesteuert werden. (auch bekannt als Verkettung ohne Leerzeichen)z.B
print(paste0("Hello","World!")) [1] "HelloWorld!" print(paste("Hello","World!", sep = "")) [1] "HelloWorld!"
Katze()
Auf der anderen Seite werden
cat()
all diese Kritikpunkte angesprochen. Vor allem dessep=" "
Parameter derpaste()
ist Funktionalität gebaut eine in denen ein Schreiben überspringenpaste()
innerhalbcat()
. Dercat()
einzige Nachteil der Funktion ist jedoch, dass Sie neue Zeilen über das\n
Anhängen am Ende oderfill = TRUE
(verwendet die Standarddruckbreite) erzwingen müssen .z.B
cat("Hello!\n") Hello! cat("Hello","World!\n") Hello World! cat("Hello","World!\n", sep = "") HelloWorld!
Genau aus diesem Grund sollten Sie
cat()
beim Entwerfen einerprint.*()
S3-Methode verwenden.Botschaft()
Die
message()
Funktion ist einen Schritt besser als geradecat()
! Der Grund dafür ist, dass sich die Ausgabe von herkömmlichem Klartext unterscheidet, da siestderr
stattdessen an gerichtet iststdout
. ZB Sie haben die Farbe von der Standardausgabe Schwarz auf Rot geändert, um die Aufmerksamkeit des Benutzers auf sich zu ziehen.Darüber hinaus verfügen Sie über die integrierte
paste0()
Funktionalität.message("Hello ","World!") # Note the space after Hello "Hello World!"
Darüber hinaus
message()
bietet ein Fehlerzustand, mit dem verwendet werden kanntryCatch()
z.B
tryCatch(message("hello\n"), message=function(e){cat("goodbye\n")}) goodbye
Warnung()
Die
warning()
Funktion ist nicht zufällig zu verwenden. Die Warnfunktion unterscheidet sich von der Nachrichtenfunktion hauptsächlich dadurch, dass ihr eine Zeile vorangestellt wird ("Warning message:"
) und ihr Status als problematisch angesehen wird.Sonstiges: Die gelegentliche Verwendung in einer Funktion kann beim Versuch, das Paket auf CRAN hochzuladen, versehentlich Herzschmerz auslösen, da Beispielprüfungen und Warnungen normalerweise als "Fehler" behandelt werden.
halt()
Zu guter Letzt haben wir
stop()
. Dies bringt Warnungen auf die nächste Ebene, indem die vorliegende Aufgabe vollständig beendet und die Kontrolle an den Benutzer zurückgegeben wird. Darüber hinaus hat es das schwerwiegendste Präfix mit dem"Error:"
hinzugefügten Begriff .quelle
message("hello world")
undcat("hello world", sep="\n")
beim Entwerfen eines Drucks. * S3-Methode?message()
wird roten Text haben und der andere wird nicht. Wenn Sie nun beispielsweise eine Variable hinzufügencat
, beträgtcat("hello world", "antonio", sep="\n")
der Unterschied eine Zeile mithello world
und eine andere mitantonio
. Trotzdemmessage()
wird alles auf der gleichen Linie bleiben.write
stackoverflow.com/questions/1109017/…message()
oder nichtcat()
. Ich habe mir angesehen, ob es eine ausgereifte Protokollierungsschnittstelle für R gibt, wie es heute bei den meisten Systemen der Fall ist (z. B. die slf4j- API für Java), und es gibt : futile.logger - Bei CRAN .