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

Time:04-05

I want to round my data with significant digits. Therefore I am using signif to achieve that.

For example:

signif(0.0054324, digits=2)
[1] 0.0054

However, I realised that there are some cases where signif doesn't work as I expected.

signif(1003.04, digits=3)
[1] 1000

signif(1005.04, digits=3)
[1] 1010

As you can see, in the previous examples, it seems that it is using ceiling or just giving me integers, without any digits.

Note that I don't want to work with round because I have some cases like this (see example below) and I don't want 0s.

round(0.000000054324, digits=2)
[1] 0

For that case, signif gives me exactly what I want.

signif(0.000000054324, digits=2)
[1] 5.4e-08

Does anyone have any idea about how can I fix that when I use "big" numbers? (Since it works perfectly with small ones). Or if you know any other method.

Thanks very much in advance

CodePudding user response:

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

CodePudding user response:

From ?signif:

For numeric x, signif(x, dig) is the same as round(x, dig - ceiling(log10(abs(x))))

When dig > ceiling(log10(abs(x)))) this leads to negative numbers in round(), and thus you get the rounding of your large numbers.

I would fix it like this, by limiting dig - ceiling(log10(abs(x)))) to 0:

my_signif <- function(x, digits = 4) {
  
  round(x, pmax(digits - ceiling(log10(abs(x))), 0))
  
}  



my_signif(0.0054324, digits=2)
#> [1] 0.0054
my_signif(0.000000054324, digits=2)
#> [1] 5.4e-08
my_signif(1003.04, digits=3)
#> [1] 1003
my_signif(1005.04, digits=3)
#> [1] 1005

Created on 2022-04-04 by the reprex package (v2.0.1)

  • Related