假設我有以下值向量:
input <- c(5.170669324, 8.69978618, 8.386448608, 9.765707038, 9.725934478, 6.37837945, 1.770207313, 4.64951078, 7.69234579, 8.060673651, 9.656558295, 9.933008843, 7.141666039, 2.969104213)
我現在想將這些值四舍五入為零位,這會給我:
round(input, 0)
[1] 5 9 8 10 10 6 2 5 8 8 10 10 7 3
問題是,這些數字現在加起來是 101,但我需要找到一個四舍五入的結果,正好是 100。
我的想法是我可以計算原始值與舍入值的差異,然后依次從最接近 x.5 的值開始,然后切換其方向,即在我的情況下,我有 101 作為總和,我需要下降到 100,所以我會將最接近和高于 0.5 的值(這里是 4.64...)更改為較小的數字,所以這個數字不會四舍五入為 5,而是改為 4。如果總和是 99,我會反過來做。
這聽起來像一個合理的方法還是有一個數學上更合適的方法?
uj5u.com熱心網友回復:
我認為這個演算法可以滿足您的需求。
如果四舍五入值的總和大于目標值,則向下舍入最合適的數字(距離向上舍入的整數最遠的數字)。如果需要,它會重復此程序,直到達到目標。如果四舍五入的值之和小于目標,它將四舍五入最合適的數字,直到達到目標:
round_to_target <- function(x, target = round(sum(x))) {
while(sum(round(x)) - target > 0) {
i <- which.min(ifelse(x %% 1 < 0.5, 1, x %% 1))
x[i] <- x[i] - 1
}
while(sum(round(x)) - target < 0) {
i <- which.max(ifelse(x %% 1 > 0.5, 0, x %% 1))
x[i] <- x[i] 1
}
round(x)
}
測驗你的例子,我們有
round_to_target(input)
#> [1] 5 9 8 10 10 6 2 4 8 8 10 10 7 3
sum(round_to_target(input))
#> [1] 100
為了證明它是一個通用的解決方案,讓我們生成一些加起來為 200 的亂數:
set.seed(1)
x <- diff(sort(c(0, runif(14, 0, 200), 200)))
x
#> [1] 12.3572541 22.9540964 5.0250357 0.8585288 11.9068176 21.3230473
#> [7] 2.3959637 37.7499290 11.2521361 6.3367497 5.2450108 42.2733677
#> [13] 1.9636210 7.2934957 11.0649463
請注意,對四舍五入的值求和得到的結果小于 200:
sum(round(x))
#> [1] 198
但是如果我們使用round_to_target,我們得到
round_to_target(x)
#> [1] 12 23 5 1 12 21 4 38 11 6 5 42 2 7 11
sum(round_to_target(x))
#> [1] 200
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/522294.html
標籤:r
上一篇:用字符和數字對列名進行排序
