如果标题不清楚,我道歉,但我无法简洁地解释。
给定浓度矢量,我想将最大值四舍五入到下一个数量级(即345到1000)。另外,我想将最小值四舍五入到较低的数量级(即3.2到1)。这些浓度也可能低于1,因此例如0.034需要舍入到0.01。
有什么想法吗?
答案 0 :(得分:14)
我不确定R,但这是一个简单的算法描述过程。
取数字的基数10对数,并在结果上应用天花板或地板。提高10的力量。完成。
您需要一个0的特殊情况,因为您不能将对数设为0。
答案 1 :(得分:11)
这是一个简单的功能,可以完成您的工作:
log10_ceiling <- function(x) {
10^(ceiling(log10(x)))
}
log10_ceiling(c(345, 3.2, 0.034))
# [1] 1000.0 10.0 0.1
答案 2 :(得分:2)
Hadley的plyr
包有一个非常灵活的函数叫round_any
,它可以很好地完成这个任务。以下是调用函数的方法
round_any(x, accuracy, f = round)
在您的情况下,x = 345
,accuracy = 1000
,您需要f = ceiling
。所以打电话
round_any(x = 345, accuracy = 1000, f = ceiling)
会完成这项工作
EDIT。只是看到您希望将maximum
向上舍入为ceiling
,将最小值向下舍入为floor
。更改函数调用中的f
以实现此目的。
答案 3 :(得分:2)
Mark Ransom接受的回答大多是正确的。 在Java中实现了这一点后,我发现了一些需要解决的问题:
这是我在Java中使用传递单元测试的实现
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);
}
答案 4 :(得分:1)
如果有人感兴趣,以下是Ostermiller的解决方案翻译为Python的情况:
def roundUpToNearestMagnitude(n):
if n == 0:
return 1
negative = n < 0
log = np.log10(abs(n))
if log > 0:
decimalPlaces = np.ceil(log)
else:
decimalPlaces = np.floor(log) + 1
rounded = np.power(10, decimalPlaces)
if negative:
return -rounded
else:
return rounded
def test_roundUpToNearestMagnitude():
assert(100 == roundUpToNearestMagnitude(50))
assert(10 == roundUpToNearestMagnitude(5))
assert(1 == roundUpToNearestMagnitude(0.5))
assert(.1 == roundUpToNearestMagnitude(0.05))
assert(.01 == roundUpToNearestMagnitude(0.005))
assert(-100 == roundUpToNearestMagnitude(-50))
assert(-10 == roundUpToNearestMagnitude(-5))
assert(-1 == roundUpToNearestMagnitude(-0.5))
assert(-.1 == roundUpToNearestMagnitude(-0.05))
assert(-.01 == roundUpToNearestMagnitude(-0.005))
assert(1 == roundUpToNearestMagnitude(0))