1

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

emr2
  • 1,436
  • 7
  • 23
  • Maybe it would be worth giving a specification of what you want, because it doesn't seem to match the usual definition of "significant digits". It seems like a custom function that rounds if numbers are bigger than 1, or uses `signif()` otherwise might be it? – Miff Apr 04 '22 at 11:02

2 Answers2

2

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
Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
1

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)

jpiversen
  • 3,062
  • 1
  • 8
  • 12