Algorithm for rounding to the next order of magnitude in R

I apologize if the title is not clear, but I could not explain it briefly.

Given the concentration vector, I would like to round up the maximum value to the next order of magnitude (i.e., from 345 to 1000). In addition, I would like to round the minimum value to a lower order (i.e., 3.2 to 1). These concentrations can also be lower than 1, therefore, for example, 0.034 must be rounded to 0.01.

Any ideas?

+6
source share
4 answers

I'm not sure about R, but this is a simple process to describe the algorithm.

Take the logarithm of base 10 and apply a ceiling or floor to the result. Raise 10 to this power. Done.

You need a special case for 0 because you cannot take the logarithm of 0.

+12
source

Here is a simple function that does what you do:

log10_ceiling <- function(x) { 10^(ceiling(log10(x))) } log10_ceiling(c(345, 3.2, 0.034)) # [1] 1000.0 10.0 0.1 
+8
source

The Hadley plyr has an extremely flexible round_any function that makes it elegant. Here is how you could call a function

 round_any(x, accuracy, f = round) 

In your case x = 345 , accuracy = 1000 and you want f = ceiling . Therefore challenge

 round_any(x = 345, accuracy = 1000, f = ceiling) 

will complete the task

EDIT. Just saw that you want maximum round to ceiling , and minimum values ​​to round to floor . change f in the function call to achieve this.

+1
source

Mark Ransom's accepted answer is basically correct. By implementing this in Java, I found a few more areas that need to be addressed:

  • Negative numbers must be handled specifically if you want -375 to give -1000
  • Ceiling for positive log values, gender + 1 for negative log values ​​(plus one is important if you want 0.456 to get 1).

Here is my implementation in Java with passing unit tests

 static double roundUpToNearestMagnitude(double n) { if (n == 0d) return 1d; boolean negative = n < 0; double log = Math.log10(Math.abs(n)); double decimalPlaces = ((log > 0)) ? (Math.ceil(log)) : (Math.floor(log) + 1); double rounded = Math.pow(10, decimalPlaces); return negative ? -rounded : rounded; } @Test public void roundUpToNearestMagnitudeFifty() { Assert.assertEquals(100d, roundUpToNearestMagnitude(50d), 0.000001); } @Test public void roundUpToNearestMagnitudeFive() { Assert.assertEquals(10d, roundUpToNearestMagnitude(5d), 0.000001); } @Test public void roundUpToNearestMagnitudeZeroPointFive() { Assert.assertEquals(1d, roundUpToNearestMagnitude(0.5d), 0.000001); } @Test public void roundUpToNearestMagnitudeZeroPointZeroFive() { Assert.assertEquals(.1d, roundUpToNearestMagnitude(0.05d), 0.000001); } @Test public void roundUpToNearestMagnitudeZeroPointZeroZeroFive() { Assert.assertEquals(.01d, roundUpToNearestMagnitude(0.005d), 0.000001); } @Test public void roundUpToNearestMagnitudeNegativeFifty() { Assert.assertEquals(-100d, roundUpToNearestMagnitude(-50d), 0.000001); } @Test public void roundUpToNearestMagnitudeNegativeFive() { Assert.assertEquals(-10d, roundUpToNearestMagnitude(-5d), 0.000001); } @Test public void roundUpToNearestMagnitudeNegativeZeroPointFive() { Assert.assertEquals(-1d, roundUpToNearestMagnitude(-0.5d), 0.000001); } @Test public void roundUpToNearestMagnitudeNegativeZeroPointZeroFive() { Assert.assertEquals(-.1d, roundUpToNearestMagnitude(-0.05d), 0.000001); } @Test public void roundUpToNearestMagnitudeNegativeZeroPointZeroZeroFive() { Assert.assertEquals(-.01d, roundUpToNearestMagnitude(-0.005d), 0.000001); } @Test public void roundUpToNearestMagnitudeZero() { Assert.assertEquals(1, roundUpToNearestMagnitude(0d), 0.000001); } 
+1
source

Source: https://habr.com/ru/post/900150/


All Articles