Por ejemplo, supongamos que tenemos el siguiente vector:
x = c(1.5, 1.2, 1.3)
La suma total de este vector es 4, pero al momento de redondear es probable obtener como resultado este vector:
x = c(2, 1, 1)
O bien, este otro:
x = c(1, 1, 1)
Al trabajar con únicamente 3 números es fácil resolver el dilema de qué hacer para redondear respetando la suma total del vector (es decir, 4), sin embargo, al trabajar con mucho más números el problema se torna un poco más complicado.
La manera más simple de resolver esto y de evitar el roundoff error es con la siguiente función:
smart.round <- function(x) {
y <- floor(x)
indices <- tail(order(x-y), round(sum(x)) - sum(y))
y[indices] <- y[indices] + 1
y
}
v
# [1] 2.655087 3.721239 5.728534 9.082078 3.813063
sum(v)
# [1] 25
smart.round(v)
# [1] 2 4 6 9 4
sum(smart.round(v))
# [1] 25
Si lo que se desea es redondear respetando además un cierto número de decimales, se puede usar esta otra función:smart.round <- function(x, digits = 0) {
up <- 10 ^ digits
x <- x * up
y <- floor(x)
indices <- tail(order(x-y), round(sum(x)) - sum(y))
y[indices] <- y[indices] + 1
y / up
}
Este código y más detalles sobre el mismo pueden consultarse en:https://stackoverflow.com/questions/32544646/round-vector-of-numerics-to-integer-while-preserving-their-sum
No hay comentarios:
Publicar un comentario