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

Круглый, но .5 должен быть перекрыт

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

> round(0.5)
[1] 0
> round(1.5)
[1] 2
> round(2.5)
[1] 2
> round(3.5)
[1] 4
> round(4.5)
[1] 4

Но мне нужно, чтобы все значения, заканчивающиеся на .5, округлялись. Все остальные значения должны быть округлены, так как они выполняются функцией round(). Пример:

round(3.5) = 3
round(8.6) = 9
round(8.1) = 8
round(4.5) = 4

Есть ли быстрый способ сделать это?

4b9b3361

Ответ 1

В комментариях к Dietrich Epp вы можете использовать функцию ceiling() со смещением, чтобы получить быстрое, векторное, правильное решение:

round_down <- function(x) ceiling(x - 0.5)
round_down(seq(-2, 3, by = 0.5))
## [1] -2 -2 -1 -1  0  0  1  1  2  2  3

Я думаю, что это быстрее и намного проще, чем многие другие показанные здесь решения.

Как отмечает Carl Witthoft, это добавляет гораздо больше предвзятости к вашим данным, чем простое округление. Для сравнения:

mean(round_down(seq(-2, 3, by = 0.5)))
## [1] 0.2727273
mean(round(seq(-2, 3, by = 0.5)))
## [1] 0.4545455
mean(seq(-2, 3, by = 0.5))
## [1] 0.5

Что такое приложение для такой процедуры округления?

Ответ 2

Убедитесь, что остаток x %% 1 равен .5, а затем поместите или округлите числа:

x <- seq(1, 3, 0.1)
ifelse(x %% 1 == 0.5, floor(x), round(x))
> 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3

Ответ 3

Я тоже присоединяюсь к цирю:

rndflr <- function(x) {
  sel <- vapply(x - floor(x), function(y) isTRUE(all.equal(y, 0.5)), FUN.VALUE=logical(1))
  x[sel] <- floor(x[sel])
  x[!sel] <- round(x[!sel])  
  x
}

rndflr(c(3.5,8.6,8.1,4.5))
#[1] 3 9 8 4

Ответ 4

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

f <- function(x) {
    round(x - .1*(x%%1 == .5))
}

x <- c(0.5,1,1.5,2,2.5,2.01,2.99)
f(x)
[1] 0 1 1 2 2 2 3

Ответ 5

Функция (не в гольф) очень проста и проверяет, остались ли оставшиеся десятичные знаки .5 или меньше. Фактически вы можете легко сделать его более полезным и принять 0.5 в качестве аргумента:

nice.round <- function(x, myLimit = 0.5) {
  bX <- x
  intX <- as.integer(x)
  decimals <- x%%intX
  if(is.na(decimals)) {
    decimals <- 0
  }
  if(decimals <= myLimit) {
    x <- floor(x)
  } else {
    x <- round(x)
  }
  if (bX > 0.5 & bX < 1) {
    x <- 1
  }
  return(x)
}

Испытания

В настоящее время эта функция работает неправильно со значениями от 0,5 до 1,0.

> nice.round(1.5)
[1] 1
> nice.round(1.6)
[1] 2
> nice.round(10000.624541)
[1] 10001
> nice.round(0.4)
[1] 0
> nice.round(0.6)
[1] 1