Compact Numeric Formatting
formatN.RdA simple utility getting more compact numeric representations, currently for “exponential” aka “scientific” format.
Usage
formatN(x, digits = 1L, sci = c(-1L, -2L))Arguments
- x
numeric or complex vector of numbers.
- digits
positive integer number of digits to use.
- sci
one or two small integers specifying
format.default'sscientificargument (seeoptions("scipen")) forabs(x) < 1and \(\ge 1\). Note that the default(-2. -1)seems optimal; this argument exists mostly to explore possibilities and to prove optimality of its default.
Value
a character vector of the same length as x.
Examples
(x <- c(outer(c(1,pi), 10^(-10:11))))
#> [1] 1.000000e-10 3.141593e-10 1.000000e-09 3.141593e-09 1.000000e-08
#> [6] 3.141593e-08 1.000000e-07 3.141593e-07 1.000000e-06 3.141593e-06
#> [11] 1.000000e-05 3.141593e-05 1.000000e-04 3.141593e-04 1.000000e-03
#> [16] 3.141593e-03 1.000000e-02 3.141593e-02 1.000000e-01 3.141593e-01
#> [21] 1.000000e+00 3.141593e+00 1.000000e+01 3.141593e+01 1.000000e+02
#> [26] 3.141593e+02 1.000000e+03 3.141593e+03 1.000000e+04 3.141593e+04
#> [31] 1.000000e+05 3.141593e+05 1.000000e+06 3.141593e+06 1.000000e+07
#> [36] 3.141593e+07 1.000000e+08 3.141593e+08 1.000000e+09 3.141593e+09
#> [41] 1.000000e+10 3.141593e+10 1.000000e+11 3.141593e+11
sum(nchar(f1 <- format(x, digits=1))) # 220
#> [1] 220
sum(nchar(f2 <- sapply(x, format, digits=1)))# 194
#> [1] 194
sum(nchar(ff1<- formatN(x, sci=-1L))) # 152
#> [1] 152
sum(nchar(ff2<- formatN(x, sci=-2L))) # 150
#> [1] 150
sum(nchar(ff <- formatN(x))) # 150 .. the best
#> [1] 150
sum(nchar(ff3<- formatN(x, sci=-3L))) # 152
#> [1] 152
noquote(rbind(f1, f2, ff1, ff, ff2, ff3))
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
#> f1 1e-10 3e-10 1e-09 3e-09 1e-08 3e-08 1e-07 3e-07 1e-06 3e-06 1e-05 3e-05
#> f2 1e-10 3e-10 1e-09 3e-09 1e-08 3e-08 1e-07 3e-07 1e-06 3e-06 1e-05 3e-05
#> ff1 1e-10 3e-10 1e-9 3e-9 1e-8 3e-8 1e-7 3e-7 1e-6 3e-6 1e-5 3e-5
#> ff 1e-10 3e-10 1e-9 3e-9 1e-8 3e-8 1e-7 3e-7 1e-6 3e-6 1e-5 3e-5
#> ff2 1e-10 3e-10 1e-9 3e-9 1e-8 3e-8 1e-7 3e-7 1e-6 3e-6 1e-5 3e-5
#> ff3 1e-10 3e-10 1e-9 3e-9 1e-8 3e-8 1e-7 3e-7 1e-6 3e-6 1e-5 3e-5
#> [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24]
#> f1 1e-04 3e-04 1e-03 3e-03 1e-02 3e-02 1e-01 3e-01 1e+00 3e+00 1e+01 3e+01
#> f2 1e-04 3e-04 0.001 0.003 0.01 0.03 0.1 0.3 1 3 10 31
#> ff1 1e-4 3e-4 1e-3 3e-3 0.01 0.03 0.1 0.3 1 3 10 31
#> ff 1e-4 3e-4 1e-3 3e-3 0.01 0.03 0.1 0.3 1 3 10 31
#> ff2 1e-4 3e-4 1e-3 3e-3 1e-2 3e-2 0.1 0.3 1 3 10 31
#> ff3 1e-4 3e-4 1e-3 3e-3 1e-2 3e-2 1e-1 3e-1 1 3 10 31
#> [,25] [,26] [,27] [,28] [,29] [,30] [,31] [,32] [,33] [,34] [,35] [,36]
#> f1 1e+02 3e+02 1e+03 3e+03 1e+04 3e+04 1e+05 3e+05 1e+06 3e+06 1e+07 3e+07
#> f2 100 314 1000 3142 10000 31416 1e+05 3e+05 1e+06 3e+06 1e+07 3e+07
#> ff1 100 314 1000 3142 1e4 3e4 1e5 3e5 1e6 3e6 1e7 3e7
#> ff 100 314 1e3 3e3 1e4 3e4 1e5 3e5 1e6 3e6 1e7 3e7
#> ff2 100 314 1e3 3e3 1e4 3e4 1e5 3e5 1e6 3e6 1e7 3e7
#> ff3 1e2 3e2 1e3 3e3 1e4 3e4 1e5 3e5 1e6 3e6 1e7 3e7
#> [,37] [,38] [,39] [,40] [,41] [,42] [,43] [,44]
#> f1 1e+08 3e+08 1e+09 3e+09 1e+10 3e+10 1e+11 3e+11
#> f2 1e+08 3e+08 1e+09 3e+09 1e+10 3e+10 1e+11 3e+11
#> ff1 1e8 3e8 1e9 3e9 1e10 3e10 1e11 3e11
#> ff 1e8 3e8 1e9 3e9 1e10 3e10 1e11 3e11
#> ff2 1e8 3e8 1e9 3e9 1e10 3e10 1e11 3e11
#> ff3 1e8 3e8 1e9 3e9 1e10 3e10 1e11 3e11
## the best is ff (where sci differs for neg.exp and pos.ex) - for this example
## the "extreme" formatting still keeps "95%" of numerical info :
stopifnot(all.equal(x, as.numeric(formatN(x)), tolerance = 0.05))