Чем объясняется округление до 1 десятичного знака x.x5 в R? - PullRequest
0 голосов
/ 07 июня 2019

Я ищу объяснение того, как округление с 1 десятичным знаком работает для такой последовательности в R:

seq(1.05, 2.95, by = .1)

В старшей школе я бы это округлил, т. Е. 2.05 становится 2.1. Но R округляет его до 2 для округления до 1 десятичного знака.

Округление от .5

Следующая функция округления из приведенного выше ответа stackoverflow последовательно выполняет округление средней школы:

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
}

Этот код сравнивает округление R и округление сверху.

data.frame(cbind(
  Number = seq(1.05, 2.95, by = .1), 
  Popular.Round = round2(seq(1.05, 2.95, by = .1), 1),
  R.Round = round(seq(1.05, 2.95, by = .1), 1)))

При округлении R 1.05 округляется до 1,1, тогда как 2,05 округляется до 2. Затем снова 1,95 округляется до 2, а 2,95 округляется до 3.

Если оно "округлено до четного", то почему оно равно 3, то есть нечетное число.

Есть ли лучший ответ, чем "просто разобраться с этим", когда его спросят об этом поведении?

1 Ответ

2 голосов
/ 07 июня 2019

Слишком долго читать? Прокрутите ниже

Это было интересное исследование лично для меня. Согласно документации:

Обратите внимание, что для округления 5, стандарт МЭК 60559 (см. Также ‘IEEE 754 ’), как ожидается, будет использоваться,« перейти к четной цифре ». Следовательно раунд (0,5) равен 0, а раунд (-1,5) равен -2. Однако это зависит от Службы ОС и ошибки представления (так как, например, 0,15 не в точности представленное, правило округления применяется к представленному число, а не на напечатанное число, и поэтому круг (0,15, 1) может быть либо 0,1, либо 0,2).

Округление до отрицательного числа цифр означает округление до степени десять, например, округление (x, цифры = -2) округляет до ближайшего сто.

Для обозначения распознанные значения цифр 1 ... 22 и не пропущены значения округляются до ближайшего целого числа в этом диапазоне. Сложный числа округляются, чтобы сохранить указанное количество цифр в больше из компонентов. Каждый элемент вектора округляется индивидуально, в отличие от печати. ​​

Во-первых, вы спросили "Если это" округление до четного ", почему оно равно 3, то есть нечетное число." Для ясности, правило округления до четного применяется для округления до 5. Если вы запускаете round(2.5) или round(3.5), затем R возвращает 2 и 4 соответственно.

Если вы идете сюда, https://stat.ethz.ch/pipermail/r-help/2008-June/164927.html,, то вы увидите этот ответ:

Логика раунда к четному правилу заключается в том, что мы пытаемся представляют базовое непрерывное значение, и если х происходит из действительно непрерывное распределение, то вероятность того, что х == 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 (или другое небольшое число) до ваших значений непосредственно перед округлением, но это может смещать ваши оценки вверх.

Короткий ответ : Если вы всегда округляете 5 с, то ваши данные смещаются вверх. Но если вы округляете по четным, то ваши округленные данные в целом становятся сбалансированными.

Давайте проверим это, используя ваши данные:

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 <- data.frame(cbind(
  Number = seq(1.05, 2.95, by = .1), 
  Popular.Round = round2(seq(1.05, 2.95, by = .1), 1),
  R.Round = round(seq(1.05, 2.95, by = .1), 1)))

> mean(x$Popular.Round)
[1] 2.05
> mean(x$R.Round)
[1] 2.02

Использование большего образца:

x <- data.frame(cbind(
  Number = seq(1.05, 6000, by = .1), 
  Popular.Round = round2(seq(1.05, 6000, by = .1), 1),
  R.Round = round(seq(1.05, 6000, by = .1), 1)))

> mean(x$Popular.Round)
[1] 3000.55
> mean(x$R.Round)
[1] 3000.537
...