Arredondar de 0,5

Sim, eu sei porque nós sempre arredondamos para o número par mais próximo se estamos no meio exato (ou seja, 2,5 se torna 2) de dois números. Mas quando quero avaliar dados para algumas pessoas, eles não querem esse comportamento. Qual é o método mais simples para obter isso:

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

ser 1,2,3, …, 10 e não 0,2,2,4,4, …, 10.

Edit: Para limpar: 1.4999 deve ser 1 após o arredondamento. (Eu pensei que isso seria óbvio)

Esta não é uma function minha e, infelizmente, não consigo encontrá-la no momento (originalmente encontrada como um comentário anônimo no blog Statistically Significant ), mas deve ajudar com o que você precisa.

 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 é o object que você deseja arredondar e n é o número de dígitos para o qual você está arredondando.

Um exemplo

 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 

Se você quer algo que se comporta exatamente como round exceto para aqueles valores xxx.5, tente isto:

 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 

Isso parece funcionar:

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

A resposta de Ananda Mahto parece fazer isso e muito mais - não tenho certeza de qual é o código extra em sua resposta; ou, em outras palavras, não consigo descobrir como quebrar a function rnd () definida acima.

Exemplo:

 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 o @CarlWitthoft disse nos comentários, este é o padrão IEC 60559, como mencionado em: ?round :

Note que para arredondar um 5, espera-se que o padrão IEC 60559 seja usado, ‘vá para o dígito par’. Portanto, round (0.5) é 0 e round (-1.5) é -2. No entanto, isso depende dos serviços do SO e do erro de representação (como, por exemplo, 0,15 não é representado exatamente, a regra de arredondamento aplica-se ao número representado e não ao número impresso, e assim por diante (0,15, 1) pode ser 0,1 ou 0,2 ).

Uma explicação adicional por Greg Snow:

A lógica por trás da regra de round to even é que estamos tentando representar um valor contínuo subjacente e se x vem de uma distribuição verdadeiramente contínua, então a probabilidade de que x == 2.5 é 0 e o 2.5 provavelmente já foi arredondado uma vez de qualquer valor entre 2.45 e 2.54999999999999 …, se usarmos o arredondamento na regra 0.5 que aprendemos na escola, então o arredondamento duplo significa que valores entre 2.45 e 2.50 serão arredondados para 3 (tendo sido arredondados para 2.5). Isso tenderá a influenciar as estimativas para cima. Para remover o viés, precisamos voltar antes do arredondamento para 2.5 (o que geralmente é impossível de ser prático), ou arredondar metade do tempo e arredondar para baixo metade do tempo (ou melhor seria arredondar proporcionalmente à probabilidade de são para valores abaixo ou acima de 2.5 arredondados para 2.5, mas isso será próximo de 50/50 para a maioria das distribuições subjacentes). A abordagem estocástica seria fazer com que a function round escolhesse aleatoriamente o caminho a percorrer, mas os tipos determinísticos não são comforatable com isso, então “round to even” foi escolhido (round to odd deve funcionar da mesma forma) como uma regra consistente que arredonda para cima e para baixo cerca de 50/50.

Se você está lidando com dados em que 2.5 provavelmente representa um valor exato (dinheiro, por exemplo), então você pode fazer melhor multiplicando todos os valores por 10 ou 100 e trabalhando em números inteiros, depois convertendo de volta apenas para a impressão final. Note que 2,50000001 arredonda para 3, então se você mantiver mais dígitos de precisão até a impressão final, então o arredondamento irá na direção esperada, ou você pode adicionar 0.000000001 (ou outro pequeno número) aos seus valores antes do arredondamento, mas isso pode bias suas estimativas para cima.

Dependendo de como você está confortável em mexer com seus dados, isso funciona:

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