﻿ Controlling Number of Decimal Digits in Print Output in R - ITCodar

# Controlling Number of Decimal Digits in Print Output in R

## Controlling number of decimal digits in print output in R

The reason it is only a suggestion is that you could quite easily write a print function that ignored the options value. The built-in printing and formatting functions do use the `options` value as a default.

As to the second question, since R uses finite precision arithmetic, your answers aren't accurate beyond 15 or 16 decimal places, so in general, more aren't required. The gmp and rcdd packages deal with multiple precision arithmetic (via an interace to the gmp library), but this is mostly related to big integers rather than more decimal places for your doubles.

Mathematica or Maple will allow you to give as many decimal places as your heart desires.

EDIT:

It might be useful to think about the difference between decimal places and significant figures. If you are doing statistical tests that rely on differences beyond the 15th significant figure, then your analysis is almost certainly junk.

On the other hand, if you are just dealing with very small numbers, that is less of a problem, since R can handle number as small as `.Machine\$double.xmin` (usually 2e-308).

Compare these two analyses.

``x1 <- rnorm(50, 1, 1e-15)y1 <- rnorm(50, 1 + 1e-15, 1e-15)t.test(x1, y1)  #Should throw an errorx2 <- rnorm(50, 0, 1e-15)y2 <- rnorm(50, 1e-15, 1e-15)t.test(x2, y2)  #ok``

In the first case, differences between numbers only occur after many significant figures, so the data are "nearly constant". In the second case, Although the size of the differences between numbers are the same, compared to the magnitude of the numbers themselves they are large.

As mentioned by e3bo, you can use multiple-precision floating point numbers using the `Rmpfr` package.

``mpfr("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825")``

These are slower and more memory intensive to use than regular (double precision) `numeric` vectors, but can be useful if you have a poorly conditioned problem or unstable algorithm.

## Formatting Decimal places in R

Background: Some answers suggested on this page (e.g., `signif`, `options(digits=...)`) do not guarantee that a certain number of decimals are displayed for an arbitrary number. I presume this is a design feature in R whereby good scientific practice involves showing a certain number of digits based on principles of "significant figures". However, in many domains (e.g., APA style, business reports) formatting requirements dictate that a certain number of decimal places are displayed. This is often done for consistency and standardisation purposes rather than being concerned with significant figures.

Solution:

The following code shows exactly two decimal places for the number `x`.

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

For example:

``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"``

A more general function is as follows where `x` is the number and `k` is the number of decimals to show. `trimws` removes any leading white space which can be useful if you have a vector of numbers.

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

E.g.,

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

Discussion of alternatives:

The formatC answers and sprintf answers work fairly well. But they will show negative zeros in some cases which may be unwanted. I.e.,

``formatC(c(-0.001), digits = 2, format = "f")# [1] "-0.00"sprintf(-0.001, fmt = '%#.2f')# [1] "-0.00"``

One possible workaround to this is as follows:

``formatC(as.numeric(as.character(round(-.001, 2))), digits = 2, format = "f")# [1] "0.00" ``

## How to control number of decimal digits in write.table() output?

You can use the function `format()` as in:

``write.table(format(ttf.all, digits=2), 'clipboard', sep='\t',row.names=F)``

`format()` is a generic function that has methods for many classes, including data.frames. Unlike `round()`, it won't throw an error if your dataframe is not all numeric. For more details on the formatting options, see the help file via `?format`

## Setting default number of decimal places for printing

You could do this:

``print <- function(x, ...) {    if (is.numeric(x)) base::print(round(x, digits=2), ...)     else base::print(x, ...)}``

## changing the number of decimal places in `skimr` output for numeric variables

It does mention in the package docs that you can format the digits e.g. see `skim_format` function and `skim_format(numeric=list(digits=4))`. If you run this prior to `skimr::skim_to_wide(mtcars\$wt)` it is now 4 digits

Was quite difficult to find!