Skip to contents

A 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's scientific argument (see options("scipen")) for abs(x) < 1 and \(\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.

Author

Martin Maechler

See also

format, sprintf, formatC, are or can be used similarly.

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))