Controlar el número de dígitos decimales en la salida de impresión en R

Resuelto Mehper C. Palavuzlar asked hace 54 años • 4 respuestas

Hay una opción en R para controlar la visualización de dígitos. Por ejemplo:

options(digits=10)

se supone que proporciona los resultados del cálculo en 10 dígitos hasta el final de la sesión de R. En el archivo de ayuda de R, la definición del parámetro dígitos es la siguiente:

dígitos: controla el número de dígitos a imprimir al imprimir valores numéricos. Es sólo una sugerencia. Los valores válidos son 1...22 con el valor predeterminado 7

Entonces dice que esto es sólo una sugerencia. ¿Qué pasa si me gusta mostrar siempre 10 dígitos, ni más ni menos?

Mi segunda pregunta es, ¿qué pasa si me gusta mostrar más de 22 dígitos, es decir, para cálculos más precisos como 100 dígitos? ¿Es posible con base R o necesito un paquete/función adicional para eso?

Editar: Gracias a la sugerencia de jmoy, lo intenté sprintf("%.100f",pi)y dio

[1] "3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000"

que tiene 48 decimales. ¿Es este el límite máximo que R puede soportar?

Mehper C. Palavuzlar avatar Jan 01 '70 08:01 Mehper C. Palavuzlar
Aceptado

La razón por la que es sólo una sugerencia es que podría escribir fácilmente una función de impresión que ignorara el valor de las opciones. Las funciones integradas de impresión y formato utilizan el optionsvalor como predeterminado.

En cuanto a la segunda pregunta, dado que R usa aritmética de precisión finita, sus respuestas no son precisas más allá de 15 o 16 decimales, por lo que, en general, no se requieren más. Los paquetes gmp y rcdd tratan con aritmética de precisión múltiple (a través de una interfaz con la biblioteca gmp), pero esto está relacionado principalmente con números enteros grandes en lugar de más lugares decimales para sus dobles.

Mathematica o Maple te permitirán dar tantos decimales como desees.

EDITAR:
Puede resultar útil pensar en la diferencia entre decimales y cifras significativas. Si está realizando pruebas estadísticas que se basan en diferencias más allá de la decimoquinta cifra significativa, entonces es casi seguro que su análisis sea basura.

Por otro lado, si sólo se trata de números muy pequeños, eso es un problema menor, ya que R puede manejar números tan pequeños como .Machine$double.xmin(normalmente 2e-308).

Compare estos dos análisis.

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

En el primer caso, las diferencias entre números sólo ocurren después de muchas cifras significativas, por lo que los datos son "casi constantes". En el segundo caso, aunque el tamaño de las diferencias entre números es el mismo, en comparación con la magnitud de los números mismos son grandes.


Como menciona e3bo, puede usar números de coma flotante de precisión múltiple usando el Rmpfrpaquete.

mpfr("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825")

Estos son más lentos y consumen más memoria que numericlos vectores normales (de doble precisión), pero pueden ser útiles si tiene un problema mal condicionado o un algoritmo inestable.

Richie Cotton avatar Feb 18 '2010 10:02 Richie Cotton

Si está produciendo todo el resultado usted mismo, puede utilizar sprintf(), por ejemplo

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

especifica que desea formatear un número de punto flotante con diez puntos decimales (en %.10fel fes para flotante y .10especifica diez puntos decimales).

No conozco ninguna forma de obligar a las funciones de nivel superior de R a imprimir un número exacto de dígitos.

Mostrar 100 dígitos no tiene sentido si está imprimiendo los números habituales de R, ya que la mejor precisión que puede obtener usando dobles de 64 bits es de alrededor de 16 dígitos decimales (consulte .Machine$double.eps en su sistema). Los dígitos restantes serán simplemente basura.

Jyotirmoy Bhattacharya avatar Feb 18 '2010 10:02 Jyotirmoy Bhattacharya

Una solución más capaz de controlar cuántos dígitos decimales imprimir según las necesidades (si no desea imprimir ceros redundantes)

Por ejemplo, si tiene un vector elementsy le gustaría sumobtenerlo

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

Aparentemente, el último número digital se 1truncó, el resultado ideal debería ser -876.54321, pero si se configura como opción decimal de impresión fija, por ejemplo sprintf("%.10f", sum(elements)), los ceros redundantes se generan como-876.5432100000

Siguiendo el tutorial aquí: imprimir números decimales , si podemos identificar cuántos dígitos decimales hay en un determinado número numérico, como aquí en -876.54321, hay 5 dígitos decimales que se deben imprimir, entonces podemos configurar un parámetro para que formatfuncione como se muestra a continuación:

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

Podemos cambiar la decimal_lengthconsulta según cada tiempo, para que pueda satisfacer diferentes requisitos de impresión decimal.

Lampard avatar Feb 27 '2020 21:02 Lampard

Si trabaja principalmente con tibbles, existe una función que aplica dígitos: num().

Aquí hay un ejemplo:

library(tidyverse)

data <- tribble(
  
~ weight, ~ weight_selfreport,
81.5,81.66969147005445,
72.6,72.59528130671505,
92.9,93.01270417422867,
79.4,79.4010889292196,
94.6,96.64246823956442,
80.2,79.4010889292196,
116.2,113.43012704174228,
95.4,95.73502722323049,
99.5,99.8185117967332
)

data <-
  data %>%
  mutate(across(where(is.numeric), ~ num(., digits = 3)))

data
#> # A tibble: 9 × 2
#>      weight weight_selfreport
#>   <num:.3!>         <num:.3!>
#> 1    81.500            81.670
#> 2    72.600            72.595
#> 3    92.900            93.013
#> 4    79.400            79.401
#> 5    94.600            96.642
#> 6    80.200            79.401
#> 7   116.200           113.430
#> 8    95.400            95.735
#> 9    99.500            99.819

De esta forma, incluso puedes decidir tener diferentes opciones de redondeo dependiendo de cuáles sean tus necesidades. Lo encuentro muy útil y una solución bastante rápida para imprimir dfs.

Daniel D avatar Mar 24 '2022 12:03 Daniel D