Reputation: 153
I want to round a vector of values WHILE preserving the sum AND taking into account an interval number.
Let´s say I have a vector:
vector <- c(0.2, 1.8, 40.4, 10.6, 0.5, 1.5)
Now I want to round the numbers while preserving their sum of 55. This function does just that:
smart.round <- function(x) {
y <- floor(x)
indices <- tail(order(x-y), round(sum(x)) - sum(y))
y[indices] <- y[indices] + 1
y
}
smart.round(vector)
[1] 0 2 40 11 0 2
BUT I want to also take into account an interval that an user has defined. Let´s say 5. This function does just that:
mround <- function(x,base){
base*round(x/base)
}
mround(vector, 5)
[1] 0 0 40 10 0 0
Now I want to combine both functions. But I cant figure out how. Basically I would like the output to be:
vector <- c(0.2, 1.8, 40.4, 10.6, 0.5, 1.5)
combined.round(vector, 5)
[1] 0 5 40 10 0 0
(as 1.8 is closest to 5 and atleast one value needs to be rounded to 5 to preserve the sum of 55) Sum is 55 and every number has interval of 5 in the required output.
Any help or suggestions are much appreciated!
Upvotes: 1
Views: 222
Reputation: 53
I am not the one who found the solution but I guess somebody has to post it for everyone. It's a beautiful solution, thanks! @Miff
smart.round <- function(x, interval = 1){
x <- x / interval
y <- floor(x)
indices <- tail(order(x-y), round(sum(x)) - sum(y))
y[indices] <- y[indices] + 1
return(y * interval)
}
Upvotes: 1