Steuern der Anzahl der Dezimalstellen in der Druckausgabe in R.

110

In R gibt es eine Option, um die Kontrolle über die Ziffernanzeige zu erlangen. Beispielsweise:

options(digits=10)

soll die Berechnungsergebnisse bis zum Ende der R-Sitzung in 10 Ziffern angeben. In der Hilfedatei von R lautet die Definition für den Ziffernparameter wie folgt:

Ziffern: Steuert die Anzahl der Ziffern, die beim Drucken numerischer Werte gedruckt werden sollen. Es ist nur ein Vorschlag. Gültige Werte sind 1 ... 22 mit Standard 7

Es heißt also, dies sei nur ein Vorschlag. Was ist, wenn ich immer 10 Ziffern anzeigen möchte, nicht mehr oder weniger?

Meine zweite Frage ist, was ist, wenn ich mehr als 22 Stellen anzeigen möchte, dh für genauere Berechnungen wie 100 Stellen? Ist es mit Base R möglich oder brauche ich dafür ein zusätzliches Paket / eine zusätzliche Funktion?

Edit: Dank jmoys Vorschlag habe ich es versucht sprintf("%.100f",pi)und es gab

[1] "3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000"

Das hat 48 Dezimalstellen. Ist dies die maximale Grenze, die R bewältigen kann?

Mehper C. Palavuzlar
quelle
5
Nur die ersten 15 Stellen von pi sind genau. Vergleichen Sie mit dem wahren Wert joyofpi.com/pi.html
Richie Cotton
1
Du hast recht. Warum ist es in R anders?
Mehper C. Palavuzlar
4
Siehe die FAQ auf R cran.r-project.org/doc/FAQ/…
Richie Cotton
2
Mehper: Ich denke, dass Sie die rechnerische Darstellung von Zahlen in R falsch interpretieren. Vielleicht möchten Sie en.wikipedia.org/wiki/Floating_point lesen .
Shane
Zum Vergleich: Python macht genau das Gleiche: Versuchen Sie es python -c "import math; print(format(math.pi, '.100f'))". Das Ergebnis sind pi48 "echte" Dezimalstellen, die für die verbleibenden 52 Ziffern mit Nullen gefüllt sind.
Syntaxfehler

Antworten:

49

Der Grund, warum dies nur ein Vorschlag ist, ist, dass Sie ganz einfach eine Druckfunktion schreiben können, die den Optionswert ignoriert. Die integrierten Druck- und Formatierungsfunktionen verwenden optionsstandardmäßig den Wert.

Was die zweite Frage betrifft, da R eine Arithmetik mit endlicher Genauigkeit verwendet, sind Ihre Antworten nicht mehr als 15 oder 16 Dezimalstellen genau, sodass im Allgemeinen keine weiteren erforderlich sind. Die Pakete gmp und rcdd verarbeiten Arithmetik mit mehrfacher Genauigkeit (über eine Schnittstelle zur gmp-Bibliothek), dies hängt jedoch hauptsächlich mit großen Ganzzahlen zusammen und nicht mit mehr Dezimalstellen für Ihre Doubles.

Mit Mathematica oder Maple können Sie so viele Dezimalstellen angeben, wie Ihr Herz begehrt.

BEARBEITEN:
Es kann nützlich sein, über den Unterschied zwischen Dezimalstellen und signifikanten Zahlen nachzudenken. Wenn Sie statistische Tests durchführen, die auf Unterschieden beruhen, die über die 15. signifikante Zahl hinausgehen, ist Ihre Analyse mit ziemlicher Sicherheit Junk.

Wenn Sie dagegen nur mit sehr kleinen Zahlen arbeiten, ist dies weniger problematisch, da R mit Zahlen von bis zu .Machine$double.xmin(normalerweise 2e-308) umgehen kann .

Vergleichen Sie diese beiden Analysen.

x1 <- rnorm(50, 1, 1e-15)
y1 <- rnorm(50, 1 + 1e-15, 1e-15)
t.test(x1, y1)  #Should throw an error

x2 <- rnorm(50, 0, 1e-15)
y2 <- rnorm(50, 1e-15, 1e-15)
t.test(x2, y2)  #ok

Im ersten Fall treten Unterschiede zwischen Zahlen erst nach vielen signifikanten Zahlen auf, sodass die Daten "nahezu konstant" sind. Im zweiten Fall sind die Unterschiede zwischen den Zahlen zwar gleich groß, aber im Vergleich zur Größe der Zahlen selbst sind sie groß.


Wie von e3bo erwähnt, können Sie mit dem RmpfrPaket Gleitkommazahlen mit mehrfacher Genauigkeit verwenden .

mpfr("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825")

Diese sind langsamer und speicherintensiver als normale numericVektoren (mit doppelter Genauigkeit) , können jedoch nützlich sein, wenn Sie ein schlecht konditioniertes Problem oder einen instabilen Algorithmus haben.

Richie Cotton
quelle
4
Wie diese Rwiki-Seite zeigt, ermöglicht das Rmpfr-Paket eine hochpräzise Gleitkomma-Arithmetik in R.
e3bo
Aber kann Rmpfr von jedem R-Paket verwendet werden, um seine Präzision zu verbessern? Oder kann es nur die intern darauf codierten Funktionen verwenden?
Skan
2
Ich dachte nur: "Wenn Sie statistische Tests durchführen, die auf Unterschieden beruhen, die über die 15. signifikante Zahl hinausgehen, dann ist Ihre Analyse mit ziemlicher Sicherheit Junk." Aber ich fragte mich, wie viele Stellen ich als Junk bezeichnen würde, und ich dachte 5, aber ich würde gerne korrigiert stehen.
PatrickT
46

Wenn Sie die gesamte Ausgabe selbst produzieren, können Sie sprintf()z

> sprintf("%.10f",0.25)
[1] "0.2500000000"

gibt an, dass Sie eine Fließkommazahl mit zehn Dezimalstellen formatiert werden soll (in %.10fder ffür Schwimmer ist und die .10gibt an zehn Dezimalstellen).

Ich kenne keine Möglichkeit, die übergeordneten Funktionen von R zu zwingen, eine genaue Anzahl von Ziffern zu drucken.

Das Anzeigen von 100 Stellen ist nicht sinnvoll, wenn Sie die üblichen Zahlen von R drucken, da die beste Genauigkeit, die Sie mit 64-Bit-Doppel erhalten können, bei 16 Dezimalstellen liegt (siehe .Machine $ double.eps auf Ihrem System). Die restlichen Ziffern sind nur Junk.

Jyotirmoy Bhattacharya
quelle
Einige spezielle Chi-Quadrat-Tests, die ich angewendet habe, benötigten Hunderte von Dezimalstellen, um genaue Ergebnisse zu erzielen. Auch pi hat Tausende von Dezimalstellen. Deshalb habe ich mich über 100 oder mehr Ziffern gewundert.
Mehper C. Palavuzlar
14
pi hat eine unendliche Anzahl von Dezimalstellen; Das bedeutet nicht, dass ein Computer sie speichern kann.
Shane
Ich denke, dies ist ein Szenario, in dem Mathematica R.
Skan
1
@skan Glaubst du, Mathematica speichert unendlich viele Dezimalstellen?
Gregor Thomas
@ Gregor natürlich nicht, aber Sie können so viele Ziffern verwenden, wie es Ihr Speicher zulässt.
Skan
1

Eine weitere Lösung, mit der Sie steuern können, wie viele Dezimalstellen je nach Bedarf ausgedruckt werden sollen (wenn Sie keine redundanten Nullen drucken möchten).

Zum Beispiel, wenn Sie einen Vektor , wie elementsund möchten bekommen sumdavon

elements <- c(-1e-05, -2e-04, -3e-03, -4e-02, -5e-01, -6e+00, -7e+01, -8e+02)
sum(elements)
## -876.5432

Anscheinend sollte das letzte Digital als 1abgeschnitten abgeschnitten werden, das ideale Ergebnis sollte sein -876.54321, aber wenn es als feste Druckdezimaloption eingestellt ist, z. B. sprintf("%.10f", sum(elements))erzeugen redundante Nullen als-876.5432100000

Folgen Sie dem Tutorial hier: Drucken von Dezimalzahlen Wenn Sie feststellen können, wie viele Dezimalstellen in einer bestimmten numerischen Zahl enthalten sind, wie hier in -876.54321, müssen 5 Dezimalstellen gedruckt werden, können Sie einen Parameter für die folgende formatFunktion einrichten :

decimal_length <- 5
formatC(sum(elements), format = "f", digits = decimal_length)
## -876.54321

Wir können die decimal_lengthbasierend auf jeder Zeitabfrage ändern , so dass unterschiedliche Anforderungen an den Dezimaldruck erfüllt werden können.

Lampard
quelle