Home > Back-end >  Obtain the exponent which I should use in scaling to make all numbers in vector >= 1
Obtain the exponent which I should use in scaling to make all numbers in vector >= 1

Time:11-27

Let's say I have a vector of some numbers, which can be < 1, but never <= 0.

> x = abs(rnorm(30))
> x
 [1] 0.32590946 0.05018667 1.54354863 0.28925652 0.61712682 0.09444528
 [7] 0.87951971 1.46243702 0.87099892 1.28553745 0.70360649 0.58973942
[13] 1.20054389 0.94429737 0.64038139 1.04173338 0.24249771 1.67273503
[19] 0.77546385 0.33547348 1.73480609 0.20757933 1.94491872 1.10547259
[25] 1.28570768 1.37621399 0.99389595 2.14107987 2.31719369 1.24458788

And when I log the entire vector I get negative values:

> log(x)
 [1] -1.121135658 -2.992005742  0.434084070 -1.240441366 -0.482680726
 [6] -2.359734671 -0.128379302  0.380104238 -0.138114546  0.251176883
[11] -0.351536037 -0.528074505  0.182774695 -0.057314153 -0.445691353
[16]  0.040886038 -1.416763021  0.514460030 -0.254293908 -1.092212359
[21]  0.550895644 -1.572241722  0.665220187  0.100272928  0.251309290
[26]  0.319336240 -0.006122756  0.761310314  0.840356837  0.218804452

Now the min of this vector is:

> min(x)
[1] 0.05018667

My question is this. I want to scale the data by 10^x or by 2^x(depends on log) so the log performed on this scaled set will produce only positive (or non-negative) numbers. How can I get the lowest exponent that will make it so?

CodePudding user response:

Maybe this fits your needs. The function scales the values such that the minimum value gets assigned to 1 and returns the exponent as well as the scaled vector as a list:

set.seed(123)

scale_log <- function(x, base = 2) {
  y <- -log(min(x)) / log(base)

  list(exp = y, scaled = base^y * x)
}

x <- abs(rnorm(5))

scale_log(x, 2)
#> $exp
#> [1] 3.826061
#> 
#> $scaled
#> [1]  7.949063  3.264540 22.106706  1.000000  1.833650

log2(scale_log(x, 2)$scaled)
#> [1] 2.990785e 00 1.706880e 00 4.466412e 00 3.203427e-16 8.747185e-01

scale_log(x, 10)
#> $exp
#> [1] 1.151759
#> 
#> $scaled
#> [1]  7.949063  3.264540 22.106706  1.000000  1.833650

log10(scale_log(x, 10)$scaled)
#> [1] 9.003159e-01 5.138220e-01 1.344524e 00 9.643275e-17 2.633165e-01
  • Related