Contrôle du nombre de chiffres décimaux dans la sortie d'impression dans R

110

Il existe une option dans R pour contrôler l'affichage des chiffres. Par exemple:

options(digits=10)

est censé donner les résultats du calcul en 10 chiffres jusqu'à la fin de la session R. Dans le fichier d'aide de R, la définition du paramètre digits est la suivante:

chiffres: contrôle le nombre de chiffres à imprimer lors de l'impression de valeurs numériques. Ce n'est qu'une suggestion. Les valeurs valides sont 1 ... 22 avec la valeur par défaut 7

Donc, il dit que ce n'est qu'une suggestion. Que faire si j'aime toujours afficher 10 chiffres, ni plus ni moins?

Ma deuxième question est: que faire si j'aime afficher plus de 22 chiffres, c'est-à-dire pour des calculs plus précis comme 100 chiffres? Est-ce possible avec la base R, ou ai-je besoin d'un package / fonction supplémentaire pour cela?

Edit: grâce à la suggestion de jmoy, j'ai essayé sprintf("%.100f",pi)et ça a donné

[1] "3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000"

qui a 48 décimales. Est-ce la limite maximale que R peut gérer?

Mehper C. Palavuzlar
la source
5
Seuls les 15 premiers chiffres de pi sont exacts. Comparez avec la vraie valeur joyofpi.com/pi.html
Richie Cotton
1
Vous avez raison. Pourquoi est-ce différent dans R?
Mehper C. Palavuzlar
4
Voir la FAQ sur R cran.r-project.org/doc/FAQ/…
Richie Cotton
2
Mehper: Je pense que vous interprétez mal la représentation informatique des nombres dans R. Vous voudrez peut-être lire en.wikipedia.org/wiki/Floating_point .
Shane
À titre de comparaison, Python fait exactement la même chose: essayez python -c "import math; print(format(math.pi, '.100f'))". Le résultat est piavec 48 décimales "réelles", remplies de zéros pour les 52 chiffres restants.
syntaxerror

Réponses:

49

La raison pour laquelle ce n'est qu'une suggestion est que vous pouvez facilement écrire une fonction d'impression qui ignore la valeur des options. Les fonctions d'impression et de formatage intégrées utilisent la optionsvaleur par défaut.

Quant à la deuxième question, étant donné que R utilise l'arithmétique de précision finie, vos réponses ne sont pas précises au-delà de 15 ou 16 décimales, donc en général, il n'est pas nécessaire d'en avoir plus. Les paquets gmp et rcdd traitent de l'arithmétique à précision multiple (via une interace à la bibliothèque gmp), mais cela est principalement lié aux grands entiers plutôt qu'à plus de décimales pour vos doubles.

Mathematica ou Maple vous permettront de donner autant de décimales que votre cœur le désire.

EDIT:
Il peut être utile de réfléchir à la différence entre les décimales et les chiffres significatifs. Si vous effectuez des tests statistiques qui reposent sur des différences au-delà du 15e chiffre significatif, alors votre analyse est presque certainement inutile.

D'un autre côté, si vous avez affaire à de très petits nombres, c'est moins un problème, puisque R peut gérer des nombres aussi petits que .Machine$double.xmin(généralement 2e-308).

Comparez ces deux analyses.

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

Dans le premier cas, les différences entre les nombres n'apparaissent qu'après de nombreux chiffres significatifs, de sorte que les données sont "presque constantes". Dans le second cas, bien que la taille des différences entre les nombres soit la même, comparée à la grandeur des nombres eux-mêmes, elles sont importantes.


Comme mentionné par e3bo, vous pouvez utiliser des nombres à virgule flottante à précision multiple à l'aide du Rmpfrpackage.

mpfr("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825")

Ils sont plus lents et plus gourmands en mémoire à utiliser que les numericvecteurs réguliers (double précision) , mais peuvent être utiles si vous avez un problème mal conditionné ou un algorithme instable.

Coton Richie
la source
4
Comme le montre cette page Rwiki , le package Rmpfr permet une arithmétique à virgule flottante de haute précision dans R.
e3bo
Mais Rmpfr peut-il être utilisé par n'importe quel package R pour améliorer sa précision? Ou il ne peut utiliser que les fonctions codées en interne?
skan
2
Je pensais simplement que "si vous faites des tests statistiques qui reposent sur des différences au-delà du 15e chiffre significatif, alors votre analyse est presque certainement inutile." mais je me suis demandé quel serait le nombre de chiffres auquel je conclurais que c'est indésirable, et j'ai pensé à 5, mais je serais heureux de rester corrigé.
PatrickT
46

Si vous produisez vous-même l'intégralité de la sortie, vous pouvez utiliser sprintf(), par exemple

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

spécifie que vous souhaitez mettre en forme un nombre à virgule flottante avec dix décimales (dans %.10fle fest pour float et le .10spécifie dix décimales).

Je ne connais aucun moyen de forcer les fonctions de niveau supérieur de R à imprimer un nombre exact de chiffres.

Afficher 100 chiffres n'a pas de sens si vous imprimez les nombres habituels de R, car la meilleure précision que vous pouvez obtenir en utilisant des doubles 64 bits est d'environ 16 chiffres décimaux (regardez .Machine $ double.eps sur votre système). Les chiffres restants seront simplement indésirables.

Jyotirmoy Bhattacharya
la source
En fait, certains tests spéciaux du chi carré que j'ai appliqués nécessitaient des centaines de décimales pour donner des résultats précis. Pi a également des milliers de décimales. C'est pourquoi je me demandais environ 100 chiffres ou plus.
Mehper C. Palavuzlar
14
pi a un nombre infini de décimales; cela ne veut pas dire qu'un ordinateur peut les stocker.
Shane
Je suppose que c'est un scénario où Mathematica est supérieur à R.
skan
1
@skan Pensez-vous que Mathematica stocke un nombre infini de décimales?
Gregor Thomas
@Gregor bien sûr que non, mais vous pouvez autant de chiffres que votre mémoire vous le permet.
skan
1

Une autre solution capable de contrôler le nombre de chiffres décimaux à imprimer en fonction des besoins (si vous ne voulez pas imprimer des zéro (s) redondants)

Par exemple, si vous avez un vecteur elementset souhaitez obtenir sumde celui - ci

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

Apparemment, le dernier numérique a 1été tronqué, le résultat idéal devrait être -876.54321, mais s'il est défini comme une option décimale d'impression fixe, par exemple sprintf("%.10f", sum(elements)), des zéros redondants sont générés comme-876.5432100000

En suivant le didacticiel ici: impression de nombres décimaux , si vous pouvez identifier le nombre de chiffres décimaux dans le certain nombre numérique, comme ici -876.54321, il y a 5 chiffres décimaux à imprimer, nous pouvons alors configurer un paramètre pour la formatfonction comme ci-dessous:

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

Nous pouvons changer le decimal_lengthbasé sur chaque requête de temps, afin qu'il puisse satisfaire différentes exigences d'impression décimale.

Lampard
la source