Подтвердить что ты не робот

Раунд вверх от .5

Да, я знаю, почему мы всегда округляем до ближайшего четного числа, если мы находимся в точной середине (т.е. 2.5 становится 2) двух чисел. Но когда я хочу оценить данные для некоторых людей, они не хотят этого поведения. Каков самый простой способ получить это:

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

составляет 1,2,3,..., 10, а не 0,2,2,4,4,..., 10.

Изменить: очистить: 1.4999 должно быть 1 после округления. (Я думал, это будет очевидно)

4b9b3361

Ответ 1

Это не моя собственная функция, и, к сожалению, я не могу найти, где я получил ее в данный момент (первоначально найденный как анонимный комментарий в Статистически значимый блог), но он должен помочь с тем, что вам нужно.

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 - это объект, который вы хотите округлить, а n - количество цифр, к которым вы округливаете.

Пример

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

Ответ 2

Если вы хотите что-то, что ведет себя точно как round за исключением тех значений xxx.5, попробуйте следующее:

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

Ответ 3

Как сказал @CarlWitthoft в комментариях, это стандарт МЭК 60559, упомянутый в " ?round:

Обратите внимание, что для округления до 5 ожидается использование стандарта IEC 60559, "перейдите к четной цифре". Поэтому раунд (0.5) равен 0, а раунд (-1.5) равен -2. Однако это зависит от служб ОС и от ошибки представления (поскольку, например, 0,15 не представляется точно, правило округления применяется к представленному числу, а не к напечатанному числу, и поэтому округление (0,15, 1) может быть либо 0,1, либо 0,2.).

Дополнительное объяснение Грега Сноу:

Логика, лежащая в основе правила округления до четности, заключается в том, что мы пытаемся представить лежащее в основе непрерывное значение, и если x получается из действительно непрерывного распределения, то вероятность того, что x == 2,5 равно 0, а значение 2,5, вероятно, уже было округлено один раз из любых значений. между 2,45 и 2,54999999999999..., если мы используем правило округления до 0,5, которое мы изучали в начальной школе, то двойное округление означает, что значения от 2,45 до 2,50 будут округлены до 3 (округляя сначала до 2,5). Это приведет к смещению оценок в сторону повышения. Чтобы устранить смещение, нам нужно либо вернуться до округления до 2,5 (что часто невозможно сделать непрактичным), либо просто округлить вдвое больше и округлить вдвое меньше (или лучше было бы округлить пропорционально тому, насколько мы вероятны) должны видеть значения ниже или выше 2,5, округленные до 2,5, но это будет близко к 50/50 для большинства базовых распределений). Стохастический подход заключается в том, чтобы функция округления случайным образом выбирала способ округления, но детерминированные типы не сочетаются с этим, поэтому было выбрано "округление до четного" (округление до нечетного должно работать примерно одинаково) в качестве согласованного правила, которое округляет вверх и вниз около 50/50.

Если вы имеете дело с данными, где 2.5, вероятно, представляет точное значение (например, деньги), то вы можете добиться большего, умножив все значения на 10 или 100 и работая в целых числах, а затем преобразовав обратно только для окончательной печати. Обратите внимание, что 2.50000001 округляет до 3, поэтому, если вы сохраняете больше цифр точности до окончательной печати, тогда округление будет идти в ожидаемом направлении, или вы можете добавить 0,000000001 (или другое небольшое число) к своим значениям непосредственно перед округлением, но это может смещать ваши оценки вверх.

Ответ 4

Это работает:

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

Ответ Ананды Махто, похоже, делает это и многое другое - я не уверен, что учитывает дополнительный код в его ответе; или, другими словами, я не могу понять, как разбить функцию rnd(), определенную выше.

Пример:

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

Ответ 5

В зависимости от того, насколько вы комфортно перемешаете свои данные, это работает:

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