Formateo de decimales en R


264

Tengo un número, por ejemplo 1.128347132904321674821 que me gustaría mostrar como solo dos decimales cuando se muestra en la pantalla (o se escribe en un archivo). ¿Cómo se hace eso?

x <- 1.128347132904321674821

EDITAR:

El uso de:

options(digits=2)

Se ha sugerido como una posible respuesta. ¿Hay alguna manera de especificar esto dentro de un script para uso único? Cuando lo agrego a mi script, no parece hacer nada diferente y no estoy interesado en volver a escribir mucho para formatear cada número (estoy automatizando un informe muy grande).

-

Respuesta: ronda (x, dígitos = 2)



Si uno usa opciones (dígitos = 4), eso no limita los cálculos a 4 dígitos, ¿verdad? En ese caso, los programas serían mucho menos precisos. SOLO afecta el número cuando se imprime, ¿correcto?
MikeZ

controls the number of digits to print when printing numeric values. It is a suggestion only. Valid values are 1...22 with default 7. See the note in print.default about values greater than 15.de las opciones? solo afecta la salida.
Brandon Bertelsen

Tenga en cuenta que round(23, digits=2)se imprimirá 23y no 23.00. Si quieres lo último, prueba stackoverflow.com/a/12135122/180892
Jeromy Anglim

44
@PaulHurleyuk, creo que es una buena práctica en la programación usar el mínimo número de bibliotecas posible. Alguien que usa una biblioteca diferente para cada necesidad trivial generalmente termina con un desastre, archivos grandes, problemas de portabilidad, etc.
Rodrigo

Respuestas:


381

Antecedentes: algunas respuestas sugeridas en esta página (p. Ej. signif, options(digits=...)) No garantizan que se muestre un cierto número de decimales para un número arbitrario. Supongo que esta es una característica de diseño en R por la cual una buena práctica científica implica mostrar un cierto número de dígitos basados ​​en los principios de " cifras significativas ". Sin embargo, en muchos dominios (por ejemplo, estilo APA , informes comerciales), los requisitos de formato dictan que se muestre un cierto número de decimales. Esto a menudo se hace con fines de coherencia y estandarización en lugar de preocuparse por cifras significativas.

Solución :

El siguiente código muestra exactamente dos lugares decimales para el número x.

format(round(x, 2), nsmall = 2)

Por ejemplo:

format(round(1.20, 2), nsmall = 2)
# [1] "1.20"
format(round(1, 2), nsmall = 2)
# [1] "1.00"
format(round(1.1234, 2), nsmall = 2)
# [1] "1.12"

Una función más general es la siguiente, donde xestá el número y kes el número de decimales que se muestran. trimwselimina cualquier espacio en blanco inicial que pueda ser útil si tiene un vector de números.

specify_decimal <- function(x, k) trimws(format(round(x, k), nsmall=k))

P.ej,

specify_decimal(1234, 5)
# [1] "1234.00000"
specify_decimal(0.1234, 5)
# [1] "0.12340"

44
+1 Solo la respuesta que funcionó para mí, se imprime correctamente 0.0001como0.00
ThomasH

77
Siempre me ha molestado cómo funcionan format()y prettyNum()transforman los números en caracteres. ¿Cómo abordarías esto?
Waldir Leoncio

¿Qué pasa con las citas que aparecen?
F.Webber

2
@JeromyAnglim Observo que la solución anterior tiene una posible desventaja en el caso de borde de fijar el número de caracteres delante del decimal, por ejemplo, format(c(10, 1), nsmall=1)rendimientos "10.0" " 1.0"(tenga en cuenta el espacio inicial delante del 1.0. Mientras que, la sprintf()función parece garantizar un mejor formato en ambos lados del decimal, por ejemplo, sprintf(c(10,1), fmt = '%#.1f')se deshace de ese molesto espacio inicial y regresa "10.0" "1.0".
Nicholas G Reich

1
Los espacios iniciales son una característica diseñada para alinear el punto decimal cuando el resultado de formatse utiliza en una columna.
Habitante

34

Puede formatear un número, digamos x, hasta decimales como desee. Aquí xhay un número con muchos decimales. Supongamos que deseamos mostrar hasta 8 decimales de este número:

x = 1111111234.6547389758965789345
y = formatC(x, digits = 8, format = "f")
# [1] "1111111234.65473890"

Aquí format="f"da números flotantes en los lugares decimales habituales, digamos, xxx.xxx, y digitsespecifica el número de dígitos. Por el contrario, si desea obtener un número entero para mostrar, lo usaría format="d"(al igual que sprintf).


Si bien no tengo claro exactamente qué estaba preguntando el OP, a juzgar por la respuesta mejor calificada, no pude evitar observar que eso formatCes casi exclusivamente lo que uso para este propósito. Creo que esta respuesta es buena y está en la base R según la solicitud del OP.
AdamO

alguno de ustedes podría ayudar en este? stackoverflow.com/q/53279593/5224236
gpier

24

Puedes probar mi paquete formatable .

> # devtools::install_github("renkun-ken/formattable")
> library(formattable)
> x <- formattable(1.128347132904321674821, digits = 2, format = "f")
> x
[1] 1.13

Lo bueno es que xsigue siendo un vector numérico y puede hacer más cálculos con el mismo formato.

> x + 1
[1] 2.13

Aún mejor, los dígitos no se pierden, puede volver a formatear con más dígitos en cualquier momento :)

> formattable(x, digits = 6, format = "f")
[1] 1.128347

Un pinchazo tan pequeño me molesta toda la mañana. Por alguna razón, R redondearía la pantalla solo para alguna columna. Necesitaba esta solución ya que también tenía que realizar cálculos en esas columnas. Esto funciona. Gracias !
thethakuri

Me gusta formatable que cualquier función baseR. La mayor ventaja es que conserva la variable como numérica.
Lazarus Thurston

22

por 2 decimales suponiendo que desea seguir ceros al final

sprintf(5.5, fmt = '%#.2f')

lo que da

[1] "5.50"

Como @mpag menciona a continuación, parece que R a veces puede dar valores inesperados con esto y el método redondo, por ejemplo, sprintf (5.5550, fmt = '% #. 2f') da 5.55, no 5.56


1
sin embargo, aunque sprintf redondea, sprintf (5.5550, fmt = '% #. 2f') da un resultado ligeramente inesperado: 5.55. sprintf (5.555000000001, fmt = '% #. 2f') da 5.56. Esto parece ser un "problema" general con el redondeo en R, ya que el método round, nsmall da lo mismo.
mpag

Gracias @mpag, no tenía idea de que R tuvo problemas para redondear los límites, solo lo intenté con 5.565 que se redondea, mientras que 5.545 se redondea hacia abajo. Supongo que es la forma en que manejan la precisión de punto flotante. No creo haber visto este comportamiento en otros idiomas, lo que supongo que significa que tienen una solución integrada
Mark Adamson,

Creo más bien que están tratando intencionalmente los valores como limitados en el grado de precisión. Están calculando que un valor que es 5.555 es realmente tan probable que haya resultado de un valor "real" de 5.5546 como 5.5554. Sin embargo, si continúa ese tipo de juego de redondeo, 5.444445 podría (no probado) terminar como "6" si lo hace un dígito a la vez. Pero podría tener razón en que podría ser una cuestión de la representación binaria un poco por debajo o por encima de 5.55.
mpag

Sí, creo que si fuera intencional, también sería consistente entre 5.565 y 5.545. La 'aleatoriedad' me sugiere que es una cosa de representación en coma flotante.
Mark Adamson el

alguno de ustedes podría ayudar en este? stackoverflow.com/q/53279593/5224236
gpier

8

Algo como eso :

options(digits=2)

Opción de definición de dígitos:

digits: controls the number of digits to print when printing numeric values.

¿Hay alguna manera de configurar esto dinámicamente cuando se ejecuta un script?
Brandon Bertelsen

Esto funciona para la salida dentro de la consola R, pero no funciona dentro de mi script (todavía salen con .1289273982)
Brandon Bertelsen

1
Tengo un comportamiento extraño, la digitsopción no parece establecer el número de dígitos después del decimal. Por ejemplo, cuando configuro opciones (dígitos = 2), la impresión de 7.25 da como resultado 7.2, 1234.25 se convierte en 1234 y 0.25 permanece en 0.25. ¿Hay otra opción interactuando con esto?
Maxim.K

8

Comprobar funciones prettyNum, formato

tener ceros de prueba (123.1240 por ejemplo) usar sprintf(x, fmt='%#.4g')


@ 42 Yo recomendaría aprender sprintf, es básicamente un marco para el formateo
Jangorecki

1
@jangorecki No estoy seguro de tu punto. Todo lo que hice (hace más de 5 años) fue sugerir una corrección ortográfica.
IRTFM

@ 42 Creo que te quejas en el fmtargumento, lo siento!
jangorecki

Creo que el OP está después de decimales fijos en lugar de dígitos fijos. Parece que gen su respuesta es para dígitos fijos, el uso ffunciona mejor.
Mark Adamson

5

Si prefiere dígitos significativos a dígitos fijos, el comando signif podría ser útil:

> signif(1.12345, digits = 3)
[1] 1.12
> signif(12.12345, digits = 3)
[1] 12.1
> signif(12345.12345, digits = 3)
[1] 12300

1
Gracias paul Estos dos no eran exactamente lo que estaba buscando, pero signif me llevó a round (), que es exactamente lo que necesitaba. Saludos,
Brandon Bertelsen

34
Error: could not find function "fixed"
ThomasH

signiffunciona para el número específico proporcionado, pero supongo que el problema común aplicado es cuando necesita mostrar exactamente dos lugares decimales pero no sabe cuál es el número antes de tiempo. En ese caso, signifdará diferentes números de decimales dependiendo del número real.
Jeromy Anglim

3
fijo no se encuentra en ningún lado. Por favor, corríjalo, de lo contrario esta respuesta engañosa debería eliminarse.
HolaMundo

@JeromyAnglim, ¿cómo arreglamos eso cuando queremos 3sf? a veces me da 3sf, otras veces 4sf, etc. ¿cómo solucionamos esto?
christouandr7

4

La función formatC()se puede usar para formatear un número con dos decimales. Esta función proporciona dos lugares decimales incluso cuando los valores resultantes incluyen ceros finales.


3

Estoy usando esta variante para forzar la impresión de K decimales:

# format numeric value to K decimal places
formatDecimal <- function(x, k) format(round(x, k), trim=T, nsmall=k)

2

Tenga en cuenta que los objetos numéricos en R se almacenan con doble precisión , lo que le proporciona (aproximadamente) 16 dígitos decimales de precisión; el resto será ruido. Admito que el número que se muestra arriba probablemente sea solo un ejemplo, pero tiene 22 dígitos.


3
Confirmado, es solo un ejemplo. Apreté el teclado.
Brandon Bertelsen

1

Me parece que sería algo así como

library(tutoR)
format(1.128347132904321674821, 2)

Por un poco de ayuda en línea .


Encontré esto, pero requiere un paquete, estoy buscando algo dentro del paquete base.
Brandon Bertelsen

2
@brandon, format () es parte de la base. Abra R y escriba? Formato ... no se necesitan paquetes.
JD Long

Hrmmm, ¿viste lo que esto produce? [1] "1.128347" de lo contrario, tienes toda la razón acerca de que está en el paquete base, mi mal.
Brandon Bertelsen

1
Tal vez intente format.default(x, digits = 2)solo un tiro en la oscuridad, aunque en función del enlace proporcionado. Esa información es algo que a falta de lo que normalmente leía para la documentación, esperaba ver también los resultados impresos.
Tim Meers

Acabo de notar que su enlace apunta a la documentación de tutoR, que no es parte de la base.
Brandon Bertelsen

1

si solo desea redondear un número o una lista, simplemente use

round(data, 2)

Luego, los datos se redondearán a 2 decimales.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.