Format Numbers to Significant Figures Nicely in R

Format numbers to significant figures nicely in R

Sorry I never updated this at the time. None of the statements in my question, or prettynum worked. In the end I used

print(formatC(signif(numbers[n],digits=3), digits=3,format="fg", flag="#"))

which correctly coped with trailing zero's and big numbers.

How can I reduce the number of significant digits of any number in R?

> formatC( signif(1239451, digits=3), big.mark=",", format="fg")
[1] "1,240,000"
> formatC( signif(-12.1257, digits=3), big.mark=",", format="fg")
[1] "-12.1"
> formatC( signif(.0581, digits=3), big.mark=",", format="fg")
[1] "0.0581"
> formatC( signif(5, digits=3), big.mark=",", format="fg")
[1] "5"

How to format numbers in R, specifying the number of significant digits but keep significant zeroes and integer part?

format(num,3) comes very close.

format(1.23456,digits=3)
# [1] "1.23"
format(12.3456,digits=3)
# [1] "12.3"
format(123.456,digits=3)
# [1] "123"
format(1234.56,digits=3)
# [1] "1235"
format(12345.6,digits=3)
# [1] "12346"
format(1.5000,digits=3)
# [1] "1.5"
format(1.4999,digits=3)
# [1] "1.5"

Your rules are not actually internally consistent. You want 1234.56 to round down to 1234, yet you want 1.4999 to round up to 1.5.

EDIT This appears to deal with the very valid point made by @Henrik.

sigDigits <- function(x,d){
z <- format(x,digits=d)
if (!grepl("[.]",z)) return(z)
require(stringr)
return(str_pad(z,d+1,"right","0"))
}

z <- c(1.23456, 12.3456, 123.456, 1234.56, 12345.6, 1.5000, 1.4999)
sapply(z,sigDigits,d=3)
# [1] "1.23" "12.3" "123" "1235" "12346" "1.50" "1.50"

Round to significant digits *only* with decimal portion of number in R

There may be a better way, but your general approach doesn't seem unreasonable. However, you can streamline it by using floor, taking advantage of vectorization to avoid lapply, and using the mod operator to return the fractional part of each number:

my_signif = function(x, digits) floor(x) + signif(x %% 1, digits)

my_signif(x, 2)
[1] 100.13000  10.03400   1.34000   0.00034

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"

signif doesn't give me the correct number of significant digits in R

This little function should give you the results you are looking for. It works by only applying signif to the fractional part of your number, while preserving the integer part.

mysignif <- function(x, digits = 3) {
x %/% 1 + signif(x %% 1, digits)
}

mysignif(0.0054324, digits=2)
#> [1] 0.0054

mysignif(1003.04, digits=3)
#> [1] 1003.04

mysignif(1005.04, digits=3)
#> [1] 1005.04

mysignif(0.000000054324, digits=2)
#> [1] 5.4e-08

mysignif(1.0005433, digits = 3)
#> [1] 1.000543

How do you control the formatting of digits when converting lists of numbers to character?

Play with the how argument to rapply():

> rapply(x, sprintf, fmt = "%0.5f", how = "replace")
[[1]]
[1] "1.00000"

[[2]]
[[2]][[1]]
[1] "0.18041" "-0.63925"

[[2]][[2]]
[[2]][[2]][[1]]
[1] "0.14309"

For more digits, change fmt:

> rapply(x, sprintf, fmt = "%0.22f", how = "replace")
[[1]]
[1] "1.0000000000000002220446"

[[2]]
[[2]][[1]]
[1] "1.2888001496908956244880" "1.0289289081633956612905"

[[2]][[2]]
[[2]][[2]][[1]]
[1] "0.4656598705611921240610"

You can gsub() out the quotes:

> gsub("\"", "", deparse(rapply(x, function(z) sprintf(fmt = "%0.22f", z), how = "replace")))
[1] "list(1.0000000000000002220446, list(c(1.2888001496908956244880, "
[2] "1.0289289081633956612905), list(0.4656598705611921240610)))"

How to format a number with specified level of precision?

You can use the signif function to round to a given number of significant digits. If you don't want extra trailing 0's then don't "print" the results but do something else with them.

> somenumbers <- c(0.000001234567, 1234567.89) 
> options(scipen=5)
> cat(signif(somenumbers,3),'\n')
0.00000123 1230000
>

Is there a function in R, which returns number of significant digits?

In the interest of simplicity, let's assume that all of the values in L are precise to the third decimal place and that kappa(L) is also precise to the third decimal place. Let's also assume a convention such that a value has a precision attribute (denoted pa) equal to its order of magnitude. Thus, all of the values in L have a precision attribute of -3.

Then the count of significant figures in kappa(L) is

sigfig = ceiling(log10(abs(x))) - precision + (log10(abs(x)) %% 1 == 0)

as a general function

count_sigfig <- function(x, precision){
ceiling(log10(abs(x))) - precision + log10(abs(x)) %% 1 == 0)
}

How can I get this exact formatting in R?

Check the Signif function from VFP package.

VFP:::Signif(df$a, 3)
[1] "1.00" "23.0" "456" "1.23" "23.5" "457" "1230"


Related Topics



Leave a reply



Submit