306
votes

I have a number, for example 1.128347132904321674821 that I would like to show as only two decimal places when output to screen (or written to a file). How does one do that?

x <- 1.128347132904321674821

EDIT:

The use of:

options(digits=2)

Has been suggested as a possible answer. Is there a way to specify this within a script for one-time use? When I add it to my script it doesn't seem to do anything different and I'm not interested in a lot of re-typing to format each number (I'm automating a very large report).

--

Answer: round(x, digits=2)

14
If one uses options(digits=4), that doesn't limit the calculations to 4 digits, does it? In that case it would make programs far less accurate. It ONLY affects the number when it is printed, correct?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. from ?options it only effects output.Brandon Bertelsen
Note that round(23, digits=2) will print 23 and not 23.00. If you want the latter, try stackoverflow.com/a/12135122/180892Jeromy Anglim
@PaulHurleyuk, I think it's good practice in programming to use the minimal number of libraries as possible. Someone who uses a different library for each trivial need usually ends up with a mess, big files, portability issues, etc.Rodrigo

14 Answers

444
votes

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"
43
votes

You can format a number, say x, up to decimal places as you wish. Here x is a number with many decimal places. Suppose we wish to show up to 8 decimal places of this number:

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

Here format="f" gives floating numbers in the usual decimal places say, xxx.xxx, and digits specifies the number of digits. By contrast, if you wanted to get an integer to display you would use format="d" (much like sprintf).

31
votes

You can try my package formattable.

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

The good thing is, x is still a numeric vector and you can do more calculations with the same formatting.

> x + 1
[1] 2.13

Even better, the digits are not lost, you can reformat with more digits any time :)

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

for 2 decimal places assuming that you want to keep trailing zeros

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

which gives

[1] "5.50"

As @mpag mentions below, it seems R can sometimes give unexpected values with this and the round method e.g. sprintf(5.5550, fmt='%#.2f') gives 5.55, not 5.56

9
votes

Something like that :

options(digits=2)

Definition of digits option :

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

Check functions prettyNum, format

to have trialling zeros (123.1240 for example) use sprintf(x, fmt='%#.4g')

9
votes

If you prefer significant digits to fixed digits then, the signif command might be useful:

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

The function formatC() can be used to format a number to two decimal places. Two decimal places are given by this function even when the resulting values include trailing zeros.

4
votes

I'm using this variant for force print K decimal places:

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

Note that numeric objects in R are stored with double precision, which gives you (roughly) 16 decimal digits of precision - the rest will be noise. I grant that the number shown above is probably just for an example, but it is 22 digits long.

2
votes

Looks to me like to would be something like

library(tutoR)
format(1.128347132904321674821, 2)

Per a little online help.

1
votes

if you just want to round a number or a list, simply use

round(data, 2)

Then, data will be round to 2 decimal place.

0
votes

here's my approach from units to millions. digits parameter let me adjust the minimum number of significant values (integer + decimals). You could adjust decimal rounding inside first.

number <-function(number){
  result <- if_else(
    abs(number) < 1000000,
    format(
      number, digits = 3,
      big.mark = ".",
      decimal.mark = ","
    ),
    paste0(
      format(
        number/1000000,
        digits = 3,
        drop0trailing = TRUE,
        big.mark = ".",
        decimal.mark = ","
      ),
      "MM"
    )
  )
  # result <- paste0("$", result)
  return(result)
}
0
votes

I wrote this function that could be improve but looks like works well in corner cases. For example, in the case of 0.9995 the vote correct answer gives us 1.00 which is incorrect. I use that solution in the case that the number has no decimals.

round_correct <- function(x, digits, chars = TRUE) {
  if(grepl(x = x, pattern = "\\.")) {
    y <- as.character(x)
    pos <- grep(unlist(strsplit(x = y, split = "")), pattern = "\\.", value = FALSE)
    if(chars) {
      return(substr(x = x, start = 1, stop = pos + digits))
    }
    return(
      as.numeric(substr(x = x, start = 1, stop = pos + digits))
    )
  } else {
    return(
      format(round(x, 2), nsmall = 2)
    )
  }
}

Example:

round_correct(10.59648, digits = 2)
[1] "10.59"
round_correct(0.9995, digits = 2)
[1] "0.99"
round_correct(10, digits = 2)
[1] "10.00"