Controllo del numero di cifre decimali nell'output di stampa in R


110

C'è un'opzione in R per ottenere il controllo sulla visualizzazione delle cifre. Per esempio:

options(digits=10)

dovrebbe fornire i risultati del calcolo in 10 cifre fino alla fine della sessione R. Nel file della guida di R, la definizione del parametro digits è la seguente:

cifre: controlla il numero di cifre da stampare quando si stampano valori numerici. È solo un suggerimento. I valori validi sono 1 ... 22 con il valore predefinito 7

Quindi, dice che questo è solo un suggerimento. E se mi piace visualizzare sempre 10 cifre, non più o meno?

La mia seconda domanda è: cosa succede se mi piace visualizzare più di 22 cifre, cioè per calcoli più precisi come 100 cifre? È possibile con la base R o ho bisogno di un pacchetto / funzione aggiuntivo per questo?

Modifica: grazie al suggerimento di jmoy, ho provato sprintf("%.100f",pi)e ha dato

[1] "3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000"

che ha 48 decimali. È questo il limite massimo che R può gestire?


5
Solo le prime 15 cifre di pi greco sono accurate. Confronta con il vero valore joyofpi.com/pi.html
Richie Cotton

1
Hai ragione. Perché è diverso in R?
Mehper C. Palavuzlar


2
Mehper: Penso che tu stia interpretando male la rappresentazione computazionale dei numeri in R. Potresti voler leggere en.wikipedia.org/wiki/Floating_point .
Shane

A titolo di confronto, Python fa esattamente lo stesso: prova python -c "import math; print(format(math.pi, '.100f'))". Il risultato è picon 48 decimali "reali", riempiti da zero per le restanti 52 cifre.
errore di sintassi

Risposte:


49

Il motivo per cui è solo un suggerimento è che potresti scrivere abbastanza facilmente una funzione di stampa che ignora il valore delle opzioni. Le funzioni di stampa e formattazione integrate utilizzano il optionsvalore come predefinito.

Per quanto riguarda la seconda domanda, poiché R utilizza aritmetica di precisione finita, le tue risposte non sono accurate oltre 15 o 16 cifre decimali, quindi in generale non sono necessarie di più. I pacchetti gmp e rcdd si occupano di aritmetica di precisione multipla (tramite un'interfaccia alla libreria gmp), ma questo è per lo più correlato a numeri interi grandi piuttosto che a più cifre decimali per i tuoi double.

Mathematica o Maple ti permetteranno di fornire tutte le cifre decimali che il tuo cuore desidera.

EDIT:
Potrebbe essere utile pensare alla differenza tra cifre decimali e cifre significative. Se stai eseguendo test statistici che si basano su differenze oltre la quindicesima cifra significativa, la tua analisi è quasi certamente spazzatura.

D'altra parte, se hai a che fare solo con numeri molto piccoli, questo è un problema minore, poiché R può gestire numeri piccoli come .Machine$double.xmin(di solito 2e-308).

Confronta queste due analisi.

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

Nel primo caso, le differenze tra i numeri si verificano solo dopo molte cifre significative, quindi i dati sono "quasi costanti". Nel secondo caso, sebbene la dimensione delle differenze tra i numeri sia la stessa, rispetto alla grandezza dei numeri stessi sono grandi.


Come accennato da e3bo, puoi utilizzare numeri in virgola mobile a precisione multipla utilizzando il Rmpfrpacchetto.

mpfr("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825")

Questi sono più lenti e richiedono più memoria da usare rispetto ai numericvettori regolari (doppia precisione) , ma possono essere utili se hai un problema mal condizionato o un algoritmo instabile.


4
Come dimostra questa pagina Rwiki , il pacchetto Rmpfr consente operazioni aritmetiche in virgola mobile ad alta precisione in R.
e3bo

Ma Rmpfr può essere utilizzato da qualsiasi pacchetto R per migliorarne la precisione? Oppure può utilizzare solo le funzioni codificate internamente su di esso?
skan

2
Stavo pensando proprio questo: "Se stai facendo test statistici che si basano su differenze oltre la quindicesima cifra significativa, la tua analisi è quasi certamente spazzatura". ma mi chiedevo quale sarebbe il numero di cifre al quale concluderei che è spazzatura, e ho pensato 5, ma sarei felice di essere corretto.
PatrickT

46

Se stai producendo l'intero output da solo, puoi usare sprintf(), ad es

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

Specifica che si desidera formattare un numero decimale con punti decimali dieci (in %.10fla fè per galleggiante e le .10specifica dieci punti decimali).

Non conosco alcun modo per forzare le funzioni di livello superiore di R a stampare un numero esatto di cifre.

La visualizzazione di 100 cifre non ha senso se stai stampando i soliti numeri di R, poiché la migliore precisione che puoi ottenere usando i doppi a 64 bit è di circa 16 cifre decimali (guarda .Machine $ double.eps sul tuo sistema). Le cifre rimanenti saranno solo spazzatura.


In realtà, alcuni test chi-quadrato speciali che ho applicato richiedevano centinaia di decimali per fornire risultati accurati. Inoltre pi ha migliaia di decimali. Ecco perché mi chiedevo circa 100 o più cifre.
Mehper C. Palavuzlar

14
pi ha un numero infinito di decimali; ciò non significa che un computer possa memorizzarli.
Shane

Immagino che questo sia uno scenario in cui Mathematica è superiore a R.
skan

1
@skan Pensi che Mathematica memorizzi un numero infinito di decimali?
Gregor Thomas,

@ Gregor ovviamente no, ma puoi usare tutte le cifre che la tua memoria ti consente.
skan

1

Una soluzione in più in grado di controllare quante cifre decimali stampare in base alle esigenze (se non si vuole stampare zero ridondanti)

Ad esempio, se si dispone di un vettore come elementse vorrebbe ottenere sumdi esso

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

Apparentemente, l'ultimo digitale è 1stato troncato, il risultato ideale dovrebbe essere -876.54321, ma se impostato come opzione decimale di stampa fissa, ad esempio sprintf("%.10f", sum(elements)), zero ridondanti genera come-876.5432100000

Seguendo il tutorial qui: stampa di numeri decimali , se in grado di identificare quante cifre decimali in un certo numero numerico, come qui -876.54321, ci sono 5 cifre decimali da stampare, quindi possiamo impostare un parametro per la formatfunzione come di seguito:

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

Possiamo modificare la decimal_lengthquery basata su ogni volta, in modo che possa soddisfare diversi requisiti di stampa decimale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.