Раунд вверх от .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 после округления. (Я думал, это будет очевидно)
Ответы
Ответ 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