Redondea desde .5

Sí, sé por qué siempre redondeamos al número par más cercano si estamos en el centro exacto (es decir, 2.5 se convierte en 2) de dos números. Pero cuando quiero evaluar datos para algunas personas, no desean este comportamiento. ¿Cuál es el método más simple para obtener esto?

x <- seq(0.5,9.5,by=1) round(x) 

ser 1,2,3, …, 10 y no 0,2,2,4,4, …, 10.

Editar: Para borrar: 1.4999 debe ser 1 después del redondeo. (Pensé que esto sería obvio)

Esta no es mi función, y desafortunadamente, no puedo encontrar dónde lo obtuve en este momento (originalmente encontrado como un comentario anónimo en el blog estadísticamente significativo ), pero debería ayudar con lo que necesita.

 round2 = function(x, n) { posneg = sign(x) z = abs(x)*10^n z = z + 0.5 z = trunc(z) z = z/10^n z*posneg } 

x es el objeto que desea redondear, n es la cantidad de dígitos a los que está redondeando.

Un ejemplo

 x = c(1.85, 1.54, 1.65, 1.85, 1.84) round(x, 1) # [1] 1.8 1.5 1.6 1.8 1.8 round2(x, 1) # [1] 1.9 1.5 1.7 1.9 1.8 

Si desea algo que se comporte exactamente como una round excepto por esos valores xxx.5, intente esto:

 x <- seq(0, 1, 0.1) x # [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 floor(0.5 + x) # [1] 0 0 0 0 0 1 1 1 1 1 1 

Esto parece funcionar:

 rnd <- function(x) trunc(x+sign(x)*0.5) 

La respuesta de Ananda Mahto parece hacer esto y mucho más: no estoy seguro de lo que explica el código adicional en su respuesta; o, en otras palabras, no puedo descifrar cómo romper la función rnd () definida anteriormente.

Ejemplo:

 seq(-2, 2, by=0.5) # [1] -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 round(x) # [1] -2 -2 -1 0 0 0 1 2 2 rnd(x) # [1] -2 -2 -1 -1 0 1 1 2 2 

Como dijo @CarlWitthoft en los comentarios, este es el estándar IEC 60559 como se menciona en ?round :

Tenga en cuenta que para redondear un 5, se espera que se use el estándar IEC 60559, ‘vaya al dígito par’. Por lo tanto, round (0.5) es 0 y round (-1.5) es -2. Sin embargo, esto depende de los servicios del sistema operativo y del error de representación (ya que por ejemplo 0.15 no está representado exactamente, la regla de redondeo se aplica al número representado y no al número impreso, y round (0.15, 1) podría ser 0.1 o 0.2 )

Una explicación adicional de Greg Snow:

La lógica detrás de la regla de ronda a par es que estamos tratando de representar un valor continuo subyacente y si x proviene de una distribución verdaderamente continua, entonces la probabilidad de que x == 2.5 sea 0 y la 2.5 probablemente ya se haya redondeado una vez desde cualquier valor entre 2.45 y 2.54999999999999 …, si utilizamos la regla de redondeo de 0.5 que aprendimos en la escuela primaria, el doble redondeo significa que los valores entre 2.45 y 2.50 redondearán a 3 (redondeados primero a 2.5). Esto tenderá a sesgar las estimaciones hacia arriba. Para eliminar el sesgo tenemos que volver a antes del redondeo a 2.5 (que a menudo es imposible o poco práctico), o simplemente redondear la mitad del tiempo y redondear la mitad del tiempo (o mejor sería redondear proporcionalmente a la probabilidad de que deben ver valores por debajo o por encima de 2.5 redondeados a 2.5, pero estarán cerca de 50/50 para la mayoría de las distribuciones subyacentes). El enfoque estocástico consistiría en hacer que la función redonda elija al azar la forma de redondear, pero los tipos determinísticos no son compatibles con eso, por lo que se eligió “redondo a par” (ronda a impar debería funcionar aproximadamente igual) que una regla consistente que redondea arriba y abajo aproximadamente 50/50.

Si está tratando con datos en los que es probable que 2.5 represente un valor exacto (dinero, por ejemplo), puede hacerlo mejor multiplicando todos los valores por 10 o 100 y trabajando en números enteros, y luego convirtiendo de nuevo solo para la impresión final. Tenga en cuenta que 2.50000001 se redondea a 3, por lo que si mantiene más dígitos de precisión hasta la impresión final, el redondeo irá en la dirección esperada, o puede agregar 0.000000001 (u otro número pequeño) a sus valores justo antes del redondeo, pero eso puede predispone tus estimaciones hacia arriba.

Dependiendo de cuán cómodo te sientes con sacudir tus datos, esto funciona:

 round(x+10*.Machine$double.eps) # [1] 1 2 3 4 5 6 7 8 9 10