Controlar el número de dígitos decimales en la salida de impresión en R
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?
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 options
valor 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 Rmpfr
paquete.
mpfr("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825")
Estos son más lentos y consumen más memoria que numeric
los vectores normales (de doble precisión), pero pueden ser útiles si tiene un problema mal condicionado o un algoritmo inestable.
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 %.10f
el f
es para flotante y .10
especifica 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.
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 elements
y le gustaría sum
obtenerlo
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 1
truncó, 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 format
funcione como se muestra a continuación:
decimal_length <- 5
formatC(sum(elements), format = "f", digits = decimal_length)
## -876.54321
Podemos cambiar la decimal_length
consulta según cada tiempo, para que pueda satisfacer diferentes requisitos de impresión decimal.
Si trabaja principalmente con tibble
s, 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.