Textverarbeitung mit R: Die Funktion format() zum Formatieren von Objekten für Ausgaben
Die Funktion format() dient dazu Ausgaben zu formatieren. Meist wird sie verwendet, um Gleitkommazahlen mit einer geeigneten Anzahl von gültigen Stellen darzustellen. Diese und weitere Einsatzmöglichkeiten (wissenschaftliche Darstellung von Zahlen) sowie Eigenschaften der Implementierung von format() (wie etwa weitere Eingabewerte, der Rückgabewert von format()) werden an zahlreichen Beispielen erläutert.
- Einordnung des Artikels
- Einführung
- Die Genauigkeit der Angabe einer Gleitkommazahl
- Ein typisches Beispiel
- Übersicht
- Ausgabe von Gleitkommazahlen und ganzen Zahlen
- Das Argument digits
- Das Argument nsmall
- Die Argumente trim und drop0trailing
- Die Rundungsregeln
- Die wissenschaftliche Darstellung einer Zahl (Mantisse, Basis, Vorzeichen und Exponent)
- Der Rückgabewert von format()
- Die Funktion format() als generisch implementierte Funktion
- Die Funktion format() für Dataframes
- Die Funktion format() für Faktoren
Einordnung des Artikels
- Einführung in die Informatik
- Einführung in die Programmiersprache R
- Textverarbeitung mit R
- Die Funktion cat() zum Erzeugen von Ausgaben
- Textverarbeitung mit R: Die Funktion format() zum Formatieren von Objekten für Ausgaben
- Textverarbeitung mit R: Mit format() verwandte Funktionen
- Textverarbeitung mit R
- Einführung in die Programmiersprache R
Hilfreich sind Kenntnisse über die Funktion cat() und über die Datentypen Dataframe und Faktor wie sie in Dataframes in R: der Datentyp data frame und Faktoren in R: der Datentyp factor erklärt wurden
Fortgesetzt wird der Artikel in Textverarbeitung mit R: Mit format() verwandte Funktionen.
Einführung
Die Genauigkeit der Angabe einer Gleitkommazahl
Bei der Genauigkeit von Gleitkommazahlen (oder Fließkommazahlen) muss man drei Dinge klar unterscheiden:
- Mit welcher Genauigkeit werden die Zahlen intern gespeichert und verarbeitet?
- Mit welcher Genauigkeit werden sie per default ausgegeben, wenn keine spezielle Anweisung gegeben wird, die die Genauigkeit festlegt (etwa in einer Funktion wie print() oder cat()).
- Welche Genauigkeit ist für die Verwendung dieser Zahlen in speziellen Ausgaben geeignet (wie in Tabellen oder der Beschriftung von Diagrammen)?
Die Funktion format() hat die primäre Aufgabe, die mit der vorgegebenen Genauigkeit berechneten Zahlen möglichst einfach in eine für die aktuell benötigte Ausgabe vorzubereiten - also der dritte Punkt oben.
Dabei wird eine eine Zahl x in eine Zeichenkette umgewandelt; die Zeichenkette bildet den Rückgabewert von format(). (Ist der Eingabewert x ein Vektor oder ein anderer zusammengesetzter Datentyp, so wird ein Vektor von Zeichenketten zurückgegeben.) Das heißt aber zugleich, dass der Rückgabewert tatsächlich nur für die Ausgaben verwendet werden soll, und nicht um mit ihm weitere Berechnungen durchzuführen.
Die Eingabewerte der Funktion format() zeigt das folgende Skript:
format(x, trim = FALSE, digits = NULL, nsmall = 0L,
justify = c("left", "right", "centre", "none"),
width = NULL, na.encode = TRUE, scientific = NA,
big.mark = "", big.interval = 3L,
small.mark = "", small.interval = 5L,
decimal.mark = getOption("OutDec"),
zero.print = NULL, drop0trailing = FALSE, ...)
Ein typisches Beispiel
Die folgenden beiden Tabellen zeigen eine Wertetabelle für die Sinus-Funktion für spezielle Winkel (im Winkelmaß). Die Funktionswerte werden in der ersten Tabelle mit 10 Nachkommastellen, in der zweiten Tabelle mit lediglich 3 Nachkommastellen angegeben. Je nachdem welche Information man dem Leser vermitteln möchte, wird man die erste oder zweite Tabelle bevorzugen - man erkennt aber sofort, dass die zweite Tabelle sehr viel leichter zu lesen ist und für viele Anwendungen besser geeignet ist. Die Aufgabe der Funktion format() besteht darin, den Programmierer beim Aufbereiten von Zahlen für spezielle Ausgaben zu unterstützen.
Wertetabelle der Sinus-Funktion mit 10 Nachkommastellen:
φ | 0 | 15 | 30 | 45 | 60 | 75 | 90 |
sin φ | 0.0000000000 | 0.2588190451 | 0.5000000000 | 0.7071067812 | 0.8660254038 | 0.9659258263 | 1.0000000000 |
Wertetabelle der Sinus-Funktion mit 3 Nachkommastellen:
φ | 0 | 15 | 30 | 45 | 60 | 75 | 90 |
sin φ | 0.000 | 0.259 | 0.500 | 0.707 | 0.866 | 0.966 | 1.000 |
Übersicht
Es können hier nicht alle Argumente von format() erklärt werden. Es werden lediglich die wichtigsten Argumente an Beispielen erklärt, die man kennen sollte, wenn man format() verwendet. Hier eine kurze Übersicht:
- Darstellung von Fließkommazahlen und ganzen Zahlen mit einer geeigneten Anzahl von gültigen Stellen mit Hilfe der Argumente digits, nsmall, trim und drop0trailing.
- Einige Hinweise zu den Rundungsregeln.
- Die wissenschaftliche Darstellung einer Zahl mit scientific.
- Der Rückgabewert der Funktion format().
- Die Funktion format() als generisch implementierte Funktion.
Ausgabe von Gleitkommazahlen und ganzen Zahlen
Die wichtigste Anwendung von format() besteht darin, Zahlen mit einer geeigneten Anzahl von gültigen Stellen darzustellen. Im Folgenden werden dazu einige Beispiele angeführt und die Argumente digits, nsmall, trim und drop0trailing erläutert.
Das Argument digits
Mit dem Argument digits = NULL
lässt sich die Anzahl der gültigen Stellen einer Fließkommazahl festlegen. Das folgende Skript zeigt eine einfache Anwendung, bei der die Kreiszahl π mit verschiedenen Werten von digits aufgerufen wird.
format(pi, digits = NULL)
# [1] "3.141593"
getOption("digits")
# [1] 7
for(i in (1:20)){
cat("i = ", i, ":\n")
print(format(pi, digits = i))
}
# digits = 1 :
# [1] "3"
# digits = 2 :
# [1] "3.1"
# digits = 3 :
# [1] "3.14"
# digits = 4 :
# [1] "3.142"
# digits = 5 :
# [1] "3.1416"
# digits = 6 :
# [1] "3.14159"
# digits = 7 :
# [1] "3.141593"
# digits = 8 :
# [1] "3.1415927"
# digits = 9 :
# [1] "3.14159265"
# digits = 10 :
# [1] "3.141592654"
# digits = 11 :
# [1] "3.1415926536"
# digits = 12 :
# [1] "3.14159265359"
# digits = 13 :
# [1] "3.14159265359"
# digits = 14 :
# [1] "3.1415926535898"
# digits = 15 :
# [1] "3.14159265358979"
# digits = 16 :
# [1] "3.141592653589793"
# digits = 17 :
# [1] "3.1415926535897931"
# digits = 18 :
# [1] "3.1415926535897931"
# digits = 19 :
# [1] "3.1415926535897931"
# digits = 20 :
# [1] "3.1415926535897931"
Man kann aus dem Beispiel zahlreiche Eigenschaften der Funktion format() und des Argumentes digits ablesen:
- Wird der default-Wert
digits = NULL
verwendet (Zeile 1 und 2), so wird der Wert verwendet, der aktuell über die Option "digits" eingestellt ist (hier 7 gültige Stellen, siehe Zeile 4 und 5). - Die Anzahl der gültigen Stellen bezieht sich nicht auf die Nachkommastellen, sondern auf alle gültigen Stellen (siehe Zeile 2: der genäherte Wert von π wird mit einer Stelle vor und 6 Stellen nach dem Komma angegeben).
- Die genäherten Werte entstehen nicht durch Abschneiden der Zahlen (nach der erforderlichen Anzahl von gültigen Stellen), sondern tatsächlich durch Runden (siehe etwa Zeile 18 und 20). Näheres zu den verwendeten Rundungsregeln im folgenden Kapitel. Dazu ist es erforderlich das Argument
nsmall = 0L
zu kennen. - Laut Anweisung in der for-Schleife sollen bis zu 20 gültige Stellen angezeigt werden. Da aber die interne Rechengenauigkeit dafür nicht ausreichend ist, werden maximal 17 gültige Stellen angezeigt (siehe Zeile 43 bis 50). Würde man mehr Stellen anzeigen, wären es Zufallszahlen, die eine höhere Genauigkeit lediglich vortäuschen. Man erhält aber keine Warnung auf der Konsole, dass der gesetzte Wert von digits nicht verwendet wurde. (Die Anzahl der intern verwendeten Stellen ist plattformabhängig; mehr dazu findet sich in der Dokumentation von print.default().)
Das Skript mit den unterschiedlichen Ausgaben der Kreiszahl π zeigt die Wirkung des Argumentes digits
, wenn eine einzige Zahl x formatiert werden soll. Wird für x ein Vektor mit mehreren Komponenten verwendet, ist nicht eindeutig vorherzusehen, wie die Komponenten gerundet werden. Es ist wichtig zu wissen, dass die Formatierungsanweisung nicht an die einzelnen Komponenten weitergereicht wird, sondern dass jetzt alle Komponenten einheitlich dargestellt werden, nämlich indem alle Komponenten als Zeichenketten identischer Länge dargestellt werden. Das folgende Skript demonstriert diese einheitliche Darstellung:
format(0.5, digits = 3)
# [1] "0.5"
z <- c(0.5, 0.55, 0.555, 0.5555)
format(z, digits = 3)
# [1] "0.500" "0.550" "0.555" "0.555"
z.1 <- z + 1
format(z.1, digits = 3)
# [1] "1.50" "1.55" "1.56" "1.56"
Zeile 1 und 2: Wird die Zahl 0.5
mit digits = 3
ausgegeben, werden - was nicht ganz korrekt ist - die Nullen am Ende der Zahl abgeschnitten. Denn 3 gültige Stellen würde eigentlich bedeuten, dass man 0.500
angibt.
Zeile 4: Es wird ein Vektor mit 4 Komponenten definiert.
Zeile 5 und 6: Wird dieser Vektor mit digits = 3
ausgegeben, so erkennt man, dass jede Komponente mit 3 Nachkommastellen angegeben wird. Das heißt die Formatierungsanweisung wird nicht an die einzelnen Komponenten weitergereicht - denn dann würde die erste Komponente wieder 0.5
lauten. Stattdessen werden alle Komponenten einheitlich mit 3 Nachkommastellen angegeben. Bei der vierten Komponente führt dies dazu, dass die letzte Stelle angeschnitten wird.
Zeile 8 und 10: An dieser Ausgabe erkennt man, dass das Argument digits tatsächlich die Anzahl der gültigen Stellen und nicht die Anzahl der Nachkommastellen angibt.
Das Argument nsmall
Oftmals sind Angaben mit wenigen Nachkommastellen unerwünscht, da sie verschleiern, ob die Zahlen gerundet wurden oder tatsächlich in der dargestellten Genauigkeit vorliegen. Mit Hilfe des Argumentes nsmall kann man sie die Mindestanzahl an Nachkommastellen vorgegeben, mit der eine Zahl ausgegeben wird.
Das folgende Skript zeigt nochmals das Beispiel der Ausgabe der Kreiszahl π, wobei aber nsmall = 4
gesetzt wird; die Schleife durchläuft jetzt nur die Werte bis zu digits = 7
. Man erkennt, dass für nsmall > digits die Angabe von nsmall Vorrang hat.
for(i in (1:7)){
cat("i = ", i, ":\n")
print(format(pi, digits = i, nsmall = 4))
}
# digits = 1 :
# [1] "3.1416"
# digits = 2 :
# [1] "3.1416"
# digits = 3 :
# [1] "3.1416"
# digits = 4 :
# [1] "3.1416"
# digits = 5 :
# [1] "3.1416"
# digits = 6 :
# [1] "3.14159"
# digits = 7 :
# [1] "3.141593"
Die Argumente trim und drop0trailing
Die bisher vorgestellten Beispiele haben gezeigt, wie die Funktion format() führende Nullen und Nullen am Ende einer Zahl behandelt. Mit den Argumente trim und drop0trailing kann das Verhalten verändert werden.
Das Argument trim = FALSE
:
Oben wurde gezeigt, dass bei der Ausgabe eines Vektors mit format() alle Komponenten mit gleicher Breite angezeigt werden. Im folgenden Beispiel wird ein Vektor definiert, der aus drei Komponenten besteht mit ganzen Zahlen, die in der üblichen Darstellung unterschiedlich lang sind:
z <- c(1, 10, 100)
format(z)
# [1] " 1" " 10" "100"
format(z, trim = FALSE)
# [1] " 1" " 10" "100"
format(z, trim = TRUE)
# [1] "1" "10" "100"
Zeile 3: Wird der Vektor z an format() übergeben, so wird für jede Komponente eine Zeichenkette mit drei Zeichen erzeugt - die längste Komponente bestimmt die Länge aller Komponenten. Dazu werden vor die Zahl Leerzeichen gesetzt, bis die gemeinsame Länge erreicht wird.
Zeile 6: Wird zusätzlich trim = FALSE
gesetzt, ändert sich nichts an der Ausgabe; man erkennt, dass FALSE der default-Wert von trim, ist.
Zeile 9: Setzt man dagegen trim = TRUE
so wird für jede Komponente des Vektors eine Zeichenkette mit angemessener Länge erzeugt - die führenden Leerzeichen werden entfernt (to trim = kürzen).
Das Argument drop0trailing = FALSE
:
Auch das Argument drop0trailing besitzt den default-Wert FALSE. Im Beispiel unten wird ein Vektor mit drei Komponenten erzeugt, die eine unterschiedliche Anzahl gültiger Stellen haben.
v <- c(0.5, 0.55, 0.555)
format(v)
# [1] "0.500" "0.550" "0.555"
format(v, drop0trailing = TRUE)
# [1] "0.5" "0.55" "0.555"
Zeile 3: Mit dem default-Wert drop0trailing = FALSE
werden alle Komponenten mit gleicher Länge dargestellt, wozu Nullen angehängt werden.
Zeile 6: Mit drop0trailing = TRUE
werden diese Nullen nicht dargestellt; jetzt wird jede Komponente mit der ihr eigenen Anzahl von gültigen Stellen dargestellt.
Die Rundungsregeln
Welche Funktionen von R welche Rundungsregeln einsetzen, kann hier nicht ausführlich beschrieben werden - es soll ja nur die Funktion format() erläutert werden. Eine ausführliche Beschreibung der Funktionen zum Runden von Zahlen findet sich im R-Basis-Paket base unter Round, also eine Beschreibung der Funktionen ceiling(), floor(), trunc(), round() und signif().
Wie format() Zahlen rundet, hängt davon ab, welche der Argumente digits und nsmall gesetzt sind.
- Ist nur das Argument digits gesetzt, dann werden so viele Stellen angezeigt wie durch digits vorgegeben wird. Ausnahme sind lediglich Nullen am Ende einer Zahl, die abgeschnitten werden. Das heißt die Zahl kann dann auch mit weniger als digits Stellen angezeigt werden.
- Ist nur das Argument nsmall gesetzt, so werden mindestens nsmall Nachkommastellen angezeigt. Für digits wird dann die Voreinstellung verwendet, die mit
getOption("digits")
abgefragt werden kann. Ist die Zahl eigentlich zu kurz, um tatsächlich nsmall Nachkommastellen anzuzeigen, werden Nullen angehängt. - Sind beide Argumente digits und nsmall gesetzt, so werden mindestens nsmall Nachkommastellen angezeigt (wie unter 2. beschrieben), aber höchstens digits gültige Stellen (wie unter 1. beschrieben).
Beispiele zu 1. wurden oben bereits gezeigt.
Ein Beispiel zu 2.:
format(x = pi, nsmall = 3)
# [1] "3.141593"
format(x = 0.5, nsmall = 3)
# [1] "0.500"
Zeile 1: Die Kreiszahl π wird mit nsmall = 3
ausgegeben. Das Argument digits ist nicht gesetzt; es wird die Voreinstellung für digits verwendet.
Zeile 4: Die Zahl 0.5 soll mit mindestens 3 Nachkommastellen ausgegeben werden. Jetzt werden Nullen angehängt, um diese Bedingung zu erfüllen.
Ein Beispiel zu 3.:
format(x = 0.55, nsmall = 3, digits = 5)
# [1] "0.550"
format(x = 0.000333, nsamll = 2, digits = 4)
# [1] "0.000333"
Zeile 1: Laut nsmall = 3
müssen mindestens 3 Nachkommastellen angegeben werden; laut digits = 5
müssen eigentlich 5 gültige Stellen angegeben werden. Da für die Zahl 0.55 die fünf gültigen Stellen nur durch Anhängen von Nullen erreicht werden kann, werden nur so viele Nullen angehängt wie es nsmall = 3
erfordert.
Zeile 4: Bei der Verwendung beider Argumente nsmall und digits muss man beachten, dass führende Nullen nicht zu den gültigen Stellen gehören. Soll die Zahl 0.000333 mit 4 gültigen Stellen dargestellt werden, so wird die Zahl so dargestellt, dass die drei Dreier sichtbar sind; die vierte gültige Stelle ist eigentlich die nächste anzuhängende Null, die aber wieder abgeschnitten wird. In diesem Beispiel ist die Anweisung nsamll = 2
wirkungslos, da die Darstellung nur durch digits = 4
bestimmt wird.
In der Dokumentation zu format() kann man zum Runden nachlesen:
Numeric vectors are encoded with the minimum number of decimal places needed to display all the elements to at least the digits significant digits. However, if all the elements then have trailing zeroes, the number of decimal places is reduced until nsmall is reached or at least one element has a non-zero final digit; see also the argument documentation for big., small. etc, above. See the note in print.default about digits >= 16.
Die wissenschaftliche Darstellung einer Zahl (Mantisse, Basis, Vorzeichen und Exponent)
Mit Hilfe des Argumentes scientific = NA
kann man festlegen, ob die wissenschaftliche Schreibweise einer Zahl mit Zehnerpotenzen verwendet werden soll oder nicht. Der Wert von scientific ist entweder TRUE oder FALSE. Die Voreinstellung scientific = NA
ist gleichwertig zu scientific = FALSE
.
z <- 10000
format(x = z, scientific = FALSE)
# [1] "10000"
format(x = z, scientific = TRUE)
# [1] "1e+04"
format(x = z * pi, digits = 4, scientific = TRUE)
# [1] "3.142e+04"
Zeile 1: Eine ganze Zahl z wird definiert.
Zeile 3 und 4: Mit scientific = FALSE
wird die übliche Darstellung einer ganzen Zahl ausgegeben.
Zeile 6 und 7: Mit scientific = TRUE
wird die wissenschaftliche Schreibweise ausgewählt, in der eine Zahl mit Hilfe einer Mantisse und einer Potenz zur Basis 10 (mit Vorzeichen) dargestellt wird. Die Mantisse ist hier eine Zahl zwischen 1 und 10, die Zehnerpotenz ist dann eindeutig definiert. Erkennbar ist die wissenschaftliche Darstellung am Buchstaben e, der "Exponent" abkürzt; der Buchstabe e hat hier nichts mit der Eulerschen Zahl zu tun.
Zeile 9 und 10: Bei Gleitkommazahlen kann die wissenschaftliche Ausgabe natürlich auch mit einer Vorgabe von digits kombiniert werden.
Das folgende Skript zeigt einen Effekt, den man bei der Verwendung der wissenschaftlichen Schreibweise niemals vergessen sollte, denn sie kann leicht eine erhöhte Rechengenauigkeit vortäuschen. In Zeile 5 wird eine Zahl definiert, die im Sinne der Mathematik auf 30 Stellen genau angegeben wird. Eine unerwartete Ausgabe liefert dann aber die Ausgabe der Zahl mit scientific = FALSE
:
rm(z)
z
# Error: object 'z' not found
z <- 1e+30
format(x = z, scientific = TRUE)
# [1] "1e+30"
format(x = z, scientific = FALSE)
# [1] "1000000000000000019924668064446"
Zeile 1: Die Zahl z wird zuerst aus dem workspace entfernt.
Zeile 5: Man kann die wissenschaftliche Schreibweise natürlich verwenden, um eine Variable zu initialisieren.
Zeile 7 und 8: Die Ausgabe mit scientific = TRUE
liefert das gewünschte Ergebnis.
Zeile 9 und 10: Aber die Ausgabe mit scientific = FALSE
zeigt, dass die Genauigkeit, mit der z definiert wurde, sich natürlich nicht auf sämtliche 30 Stellen bezieht. Jenseits der Rechengenauigkeit enthält z jetzt Zufallszahlen, was bei Berechnungen berücksichtigt werden sollte.
Der Rückgabewert von format()
An den bisherigen Beispielen zum Einsatz von format() konnte man bereits ablesen:
- Ist eine einzige Zahl (Vektor der Länge 1) Eingabewert x von format(), so wird diese Zahl in eine Zeichenkette verwandelt.
- Ist der Eingabewert x ein Vektor mit mehr als einer Komponente, so wird jede Komponente in eine Zeichenkette verwandelt; sie bilden dann die Komponenten des character-Vektors, der von format() zurückgegeben wird.
Generell kann man über den Rückgabewert von format() sagen: Es wird versucht, aus dem Eingabewert x einen character-Vektor zu erzeugen, der dem Objekt möglichst gut entspricht. Je nach Datentyp von x wird auch der Rückgabewert unterschiedliche Struktur besitzen.
Daran, dass der Rückgabewert von format() ein Vektor von Zeichenketten ist, kann man ablesen, dass man format() niemals einsetzen sollte, wenn man Zahlen runden und anschließend mit ihnen weiter rechnen möchte. Denn dann müsste man erst umständlich die Zeichenketten in Zahlen verwandeln. Zum Runden sollten immer die Funktionen eingesetzt werden, die im Abschnitt über die Rundungsregeln beschrieben wurden.
Die Funktion format() als generisch implementierte Funktion
Die Funktion format() für Dataframes
Da in einem Dataframe üblicherweise die Einträge in einer Spalte inhaltlich verwandt und speziell von einem gemeinsamen Datentyp sind, ist es sinnvoll die Formatierungsanweisungen für die Spalten und nicht für die Zeilen zu definieren. In der Implementierung von format() für Dataframes wird daher einfach die Anweisung an die Spalten weitergereicht. Insbesondere wird dadurch - da jede Spalte wie ein Vektor behandelt wird - für jede Spalte eine einheitliche Anzahl von Stellen angegeben.
Aus den Beispielen, in denen gezeigt wurden, kann man ablesen, welche Wirkung die Argumente nsmall und digits haben, wenn führende Nullen in einer Zahl vorkommen oder wenn eigentlich Nullen anzuhängen sind, um die richtige Anzahl von gültigen Stellen zu erreichen. Diese Effekte führen dazu, dass in einem Dataframe zwar jede Spalte mit einheitlicher Stellenanzahl angezeigt wird, aber unterschiedliche Spalten auch einen unterschiedliche Anzahl von gültigen Stellen besitzen können. Auf den ersten Blick mag dies verwundern, da der Aufruf von format() für ein Dataframe suggeriert, dass für das gesamte Dataframe eine einheitliche Formatierungsanweisung gegeben wird.
Das folgende Beispiel soll dies demonstrieren. Wie in der Wertetabelle in der Einführung werden jetzt mehrere Winkel (im Winkelmaß) definiert und für diese die sin-, cos- und tan-Funktion berechnet. Die Winkel beziehungsweise die drei Gruppen von Funktionswerten bilden je eine Spalte eines Dataframes.
# Winkel im Winkelmaß: 0, 15, ..., 90
phis <- 15 * (0:6)
# Winkel im Bogenmaß
xs <- phis * pi / 180
sins <- sin(xs)
coss <- cos(xs)
tans <- tan(xs)
df <- data.frame(phi = phis, sin = sins, cos = coss, tan = tans)
format(df, nsamll = 2, digits = 4, scientific = FALSE)
# phi sin cos tan
# 1 0 0.0000 1.00000000000000000000 0.0000
# 2 15 0.2588 0.96592582628906831221 0.2679
# 3 30 0.5000 0.86602540378443870761 0.5774
# 4 45 0.7071 0.70710678118654757274 1.0000
# 5 60 0.8660 0.50000000000000011102 1.7321
# 6 75 0.9659 0.25881904510252073948 3.7321
# 7 90 1.0000 0.00000000000000006123 16331239353195370.0000
format(df, nsamll = 2, digits = 4, scientific = TRUE)
# phi sin cos tan
# 1 0 0.0000 1.000e+00 0.000e+00
# 2 15 0.2588 9.659e-01 2.679e-01
# 3 30 0.5000 8.660e-01 5.774e-01
# 4 45 0.7071 7.071e-01 1.000e+00
# 5 60 0.8660 5.000e-01 1.732e+00
# 6 75 0.9659 2.588e-01 3.732e+00
# 7 90 1.0000 6.123e-17 1.633e+16
Das Dataframe wird mit den Formatierungsanweisungen nsamll = 2, digits = 4
ausgegeben (Zeile 13). Die Ausgabe der sin-Werte zeigt das erwartete Ergebnis mit 4 Nachkommastellen. Dagegen entsteht bei der Berechnung der cos-Funktion bei einem Winkel von 90° ein Rundungsfehler, der dazu führt, dass der Funktionswert nicht exakt gleich 1 ist. Um die führenden Nullen darzustellen, müssen jetzt deutlich mehr als 4 Nachkommastellen angezeigt werden. Die Darstellung der tan-Werte geschieht wieder mit den 4 Nachkommastellen.
Die Verwendung der wissenschaftlichen Schreibweise (Zeile 23) hat zwar den Vorteil, dass jetzt die Nachkommastellen einheitlich behandelt werden, aber die Verwendung einer Zehnerpotenz wie 10-1 ist eher verwirrend und sie erschwert hier den Vergleich der Zahlen.
Das Argument width ist zwar schon für die default-Version von format() definiert, aber speziell bei der Ausgabe von Dataframes kann es sehr gut für eine übersichtlichere Darstellung sorgen. Im folgenden Beispiel wird das Dataframe aus dem letzten Skript mit width = 12
ausgegeben. Dadurch wird für jede Spalte eine Breite von 12 Zeichen reserviert.
format(df, nsamll = 2, digits = 4, width = 12, scientific = TRUE)
# phi sin cos tan
# 1 0.0e+00 0.000e+00 1.000e+00 0.000e+00
# 2 1.5e+01 2.588e-01 9.659e-01 2.679e-01
# 3 3.0e+01 5.000e-01 8.660e-01 5.774e-01
# 4 4.5e+01 7.071e-01 7.071e-01 1.000e+00
# 5 6.0e+01 8.660e-01 5.000e-01 1.732e+00
# 6 7.5e+01 9.659e-01 2.588e-01 3.732e+00
# 7 9.0e+01 1.000e+00 6.123e-17 1.633e+16
Die Funktion format() für Faktoren
Ein Faktor dient dazu die Elemente eines Vektors in Klassen (oder levels) einzuteilen. Wird ein Faktor mit print() ausgegeben, so werden nicht die Komponenten des Vektors angezeigt, sondern zu welcher Klasse sie gehören. Zusätzlich werden die Klassen aufgelistet.
Die Funktion format() besitzt eine eigene Implementierung für Faktoren, die dadurch geeignet ausgegeben werden können. Ein einfaches Beispiel soll dies zeigen. Im folgenden Skript wird ein Vektor definiert, in einen Faktor verwandelt und auf verschiedene Weisen ausgegeben.
Der character-Vektor v besteht aus 6 Komponenten, wobei die erste und zweite beziehungsweise dritte und vierte Komponente identisch sind (siehe Zeile 1). Bildet man mit Hilfe der Funktion factor() aus dem Vektor v einen Faktor f (siehe Zeile 2), so werden bei dessen Ausgabe die Klassen der Komponenten angegeben (siehe Zeile 4 und 5) und die im Vektor v enthaltenen levels (Klassen) werden aufgelistet (siehe Zeile 6).
Die einfachste Art, um festzustellen, wie oft jede Klasse im Vektor v enthalten ist, besteht im Aufruf von table() mit dem Faktor als Argument (siehe Zeile 8 - 10).
v <- c("A", "A", "B", "B", "C", "D")
f <- factor(x = v)
f
# [1] A A B B C D
# Levels: A B C D
table(f)
# A B C D
# 2 2 1 1
format(x = f)
# [1] "A" "A" "B" "B" "C" "D"
format(x = f, width = 4)
# [1] "A " "A " "B " "B " "C " "D "
format(x = f, width = 4, justify = "right")
# [1] " A" " A" " B" " B" " C" " D"
Zeile 12: Wird der Faktor f an die Funktion format() übergeben, werden die Komponenten ausgegeben; man erkennt an den Anführungsstrichen, dass jede Komponente eine Zeichenkette ist.
Zeile 15: Wird zusätzlich width = 4
in format() gesetzt, wird für jede Komponente eine Breite von 4 Zeichen gewählt. Per default werden die Komponenten linksbündig dargestellt; um width = 4
zu erfüllen, werden natürlich Leerzeichen verwendet.
Zeile 18: Durch die zusätzliche Angabe justify = "right"
werden die Zeichen rechtsbündig dargestellt.