Formatando casas decimais em R

264

Eu tenho um número, por exemplo, 1.128347132904321674821 que gostaria de mostrar como apenas duas casas decimais quando a saída é exibida na tela (ou gravada em um arquivo). Como é que alguém faz isso?

x <- 1.128347132904321674821

EDITAR:

O uso de:

options(digits=2)

Foi sugerido como uma resposta possível. Existe uma maneira de especificar isso em um script para uso único? Quando o adiciono ao meu script, parece não fazer nada diferente e não estou interessado em re-digitar muito para formatar cada número (estou automatizando um relatório muito grande).

-

Resposta: arredondado (x, dígitos = 2)

Brandon Bertelsen
fonte
1
Pergunta relacionada: stackoverflow.com/questions/2287616/…
Shane
Se alguém usa opções (dígitos = 4), isso não limita os cálculos a 4 dígitos, não é? Nesse caso, tornaria os programas muito menos precisos. Afeta apenas o número quando impresso, correto?
Mikez
controls the number of digits to print when printing numeric values. It is a suggestion only. Valid values are 1...22 with default 7. See the note in print.default about values greater than 15.das opções? afeta apenas a saída.
Brandon Bertelsen
Observe que round(23, digits=2)será impresso 23e não 23.00. Se você quiser o último, tente stackoverflow.com/a/12135122/180892
Jeromy Anglim 7/12/12
4
@PaulHurleyuk, acho que é uma boa prática de programação usar o número mínimo de bibliotecas possível. Alguém que usa uma biblioteca diferente para cada necessidade trivial geralmente acaba com uma bagunça, grandes arquivos, problemas de portabilidade, etc.
Rodrigo

Respostas:

381

Antecedentes: Algumas respostas sugeridas nesta página (por exemplo, signif, options(digits=...)) não garantem que um certo número de casas decimais são exibidos para um número arbitrário. Presumo que este seja um recurso de design em R, no qual boas práticas científicas envolvem mostrar um certo número de dígitos com base em princípios de " figuras significativas ". No entanto, em muitos domínios (por exemplo, estilo APA , relatórios comerciais), os requisitos de formatação determinam que um determinado número de casas decimais seja exibido. Isso geralmente é feito para fins de consistência e padronização, em vez de se preocupar com números significativos.

Solução :

O código a seguir mostra exatamente duas casas decimais para o número x.

format(round(x, 2), nsmall = 2)

Por exemplo:

format(round(1.20, 2), nsmall = 2)
# [1] "1.20"
format(round(1, 2), nsmall = 2)
# [1] "1.00"
format(round(1.1234, 2), nsmall = 2)
# [1] "1.12"

Uma função mais geral é a seguinte, onde xestá o número e ko número de casas decimais a serem exibidas. trimwsremove qualquer espaço em branco inicial que possa ser útil se você tiver um vetor de números.

specify_decimal <- function(x, k) trimws(format(round(x, k), nsmall=k))

Por exemplo,

specify_decimal(1234, 5)
# [1] "1234.00000"
specify_decimal(0.1234, 5)
# [1] "0.12340"
Jeromy Anglim
fonte
4
Uma única resposta que funcionou para mim, é impressa corretamente 0.0001como #0.00
ThomasH 6/12/12
7
Sempre me incomodou como as funções gostam format()e prettyNum()transformam números em caracteres. Como você abordaria isso?
Waldir Leoncio
O que há com as aspas que aparecem?
F.Webber
2
@JeromyAnglim Observo que a solução acima tem uma possível desvantagem de fixar o número de caracteres antes do decimal, por exemplo, format(c(10, 1), nsmall=1)yields "10.0" " 1.0"(observe o espaço à frente do 1.0. Considerando que, a sprintf()função parece garantir uma melhor formatação no ambos os lados do decimal, por exemplo, sprintf(c(10,1), fmt = '%#.1f')se livrar desse espaço levando traquinas e volta "10.0" "1.0".
Nicholas G Reich
1
Os espaços à esquerda são um recurso projetado para alinhar o ponto decimal quando o resultado de formaté usado em uma coluna.
Habitante
34

Você pode formatar um número, digamos x, com casas decimais conforme desejar. Aqui xestá um número com muitas casas decimais. Suponha que desejamos mostrar até 8 casas decimais deste número:

x = 1111111234.6547389758965789345
y = formatC(x, digits = 8, format = "f")
# [1] "1111111234.65473890"

Aqui, os format="f"números flutuantes nas casas decimais habituais dizem xxx.xxx e digitsespecifica o número de dígitos. Por outro lado, se você quisesse exibir um número inteiro, usaria format="d"(muito parecido sprintf).

SORIF HOSSAIN
fonte
Embora não esteja claro exatamente o que o OP estava perguntando, a julgar pela resposta mais bem classificada, não pude deixar de observar que formatCé quase exclusivamente o que uso para esse fim. Eu acho que essa resposta é boa e está na base R de acordo com a solicitação do OP.
Adamo
Algum de vocês poderia ajudar neste? stackoverflow.com/q/53279593/5224236
gpier 13/11
24

Você pode tentar o meu pacote formatável .

> # devtools::install_github("renkun-ken/formattable")
> library(formattable)
> x <- formattable(1.128347132904321674821, digits = 2, format = "f")
> x
[1] 1.13

O bom xé que ainda é um vetor numérico e você pode fazer mais cálculos com a mesma formatação.

> x + 1
[1] 2.13

Melhor ainda, os dígitos não são perdidos, você pode reformatar com mais dígitos a qualquer momento :)

> formattable(x, digits = 6, format = "f")
[1] 1.128347
Kun Ren
fonte
Um idiota tão minúsculo me incomodando a manhã inteira. Por alguma razão, R arredondaria a exibição apenas para alguma coluna. Eu precisava dessa correção, pois também precisava realizar cálculos nessas colunas. Isso funciona. Obrigado !
Thethakuri # 7/16
Eu gosto de formatar do que qualquer função baseR. A maior vantagem é que ela retém a variável como numérica.
Lázaro Thurston
22

por 2 casas decimais, supondo que você queira manter zeros à direita

sprintf(5.5, fmt = '%#.2f')

que dá

[1] "5.50"

Como o @mpag menciona abaixo, parece que o R às vezes pode fornecer valores inesperados com isso e o método round, por exemplo, sprintf (5.5550, fmt = '% #. 2f') fornece 5,55, e não 5,56

Mark Adamson
fonte
1
no entanto, embora o sprintf rode, o sprintf (5.5550, fmt = '% #. 2f') fornece um resultado ligeiramente inesperado: 5.55. sprintf (5.555000000001, fmt = '% #. 2f') fornece 5.56. Isso parece ser um "problema" geral com arredondamento em R, pois o método nsmall é o mesmo.
MPAG
Obrigado @mpag, eu não tinha idéia de que R lutava com o arredondamento nos limites, eu apenas tentei com o 5.565, que é arredondado, enquanto 5.545 é arredondado. Eu acho que é assim que eles estão lidando com imprecisões de ponto flutuante. Eu não acho que eu já vi esse comportamento em outros idiomas que eu acho que significa que eles têm um built-in solução alternativa
Mark Adamson
Eu acho que eles estão intencionalmente tratando os valores como limitados no grau de precisão. Eles estão imaginando que um valor que é 5.555 é realmente tão provável que tenha resultado de um valor "real" de 5.5546 quanto 5.5554. No entanto, se você continuar com esse tipo de jogo de arredondamento, 5.444445 (não testado) poderá acabar como "6" se você fizer um dígito de cada vez. Mas você pode estar certo de que pode ser uma questão de a representação binária estar um pouco abaixo ou acima de 5,55.
MPAG
Sim, acho que se fosse intencional, também seria consistente entre 5.565 e 5.545. A 'aleatoriedade' sugere para mim que é uma representação de ponto flutuante.
Mark Adamson
Algum de vocês poderia ajudar neste? stackoverflow.com/q/53279593/5224236
gpier 13/11
8

Algo parecido :

options(digits=2)

Definição da opção de dígitos:

digits: controls the number of digits to print when printing numeric values.
Xavier V.
fonte
Existe alguma maneira de definir isso dinamicamente ao executar um script?
Brandon Bertelsen
Isso funciona para a saída no console R, mas não funciona dentro do meu roteiro (eles ainda saem com 0,1289273982)
Brandon Bertelsen
1
Recebo um comportamento estranho, a digitsopção não parece definir o número de dígitos após o decimal. Por exemplo, quando eu defino opções (dígitos = 2), a impressão de 7,25 resulta na saída de 7.2, 1234.25 torna-se 1234 e 0,25 permanece 0,25. Existe outra opção interagindo com isso?
precisa saber é o seguinte
8

Verificar funções prettyNum, formato

ter zeros de teste (123.1240 por exemplo) use sprintf(x, fmt='%#.4g')

ilya
fonte
@ 42 eu defendo para aprender sprintf, é basicamente uma estrutura para formatação
jangorecki
1
@jangorecki Eu não tenho certeza do seu ponto. Tudo o que fiz (há mais de 5 anos) foi sugerir uma correção ortográfica.
IRTFM 24/03
@ 42 Eu sinto muito que você reclame sobre o fmtargumento, desculpe!
Jangorecki
Eu acho que o OP é depois de casas decimais fixas, em vez de dígitos fixos. Parece que a gsua resposta é para dígitos fixos, usando ffunciona melhor.
Mark Adamson
5

Se você preferir dígitos significativos a dígitos fixos, o comando signif pode ser útil:

> signif(1.12345, digits = 3)
[1] 1.12
> signif(12.12345, digits = 3)
[1] 12.1
> signif(12345.12345, digits = 3)
[1] 12300
PaulHurleyuk
fonte
1
Obrigado Paul. Esses dois não eram exatamente o que eu estava procurando, mas o significado me levou a round (), que é exatamente o que eu precisava. Cheers,
Brandon Bertelsen
34
Error: could not find function "fixed"
ThomasH
signiffunciona para o número específico fornecido, mas presumo que o problema comum aplicado seja quando você precisa mostrar exatamente duas casas decimais, mas não sabe qual é o número antecipado. Nesse caso, signiffornecerá números diferentes de decimais, dependendo do número real.
perfil completo de Jeromy Anglim
3
fixo não foi encontrado em nenhum lugar. Corrija-o, caso contrário, essa resposta enganosa deve ser excluída.
HelloWorld 24/04
@JeromyAnglim como podemos corrigir isso quando queremos 3sf? às vezes me dá 3sf, outras vezes 4sf, etc. como podemos corrigir isso?
christouandr7 28/03
4

A função formatC()pode ser usada para formatar um número com duas casas decimais. Duas casas decimais são fornecidas por essa função, mesmo quando os valores resultantes incluem zeros à direita.

Chernoff
fonte
3

Estou usando esta variante para forçar a impressão de casas decimais K:

# format numeric value to K decimal places
formatDecimal <- function(x, k) format(round(x, k), trim=T, nsmall=k)
Eldar Agalarov
fonte
2

Observe que objetos numéricos em R são armazenados com precisão dupla , o que fornece (aproximadamente) 16 dígitos decimais de precisão - o restante será ruído. Concordo que o número mostrado acima provavelmente seja apenas um exemplo, mas tem 22 dígitos.

nullglob
fonte
3
Confirmado, é apenas um exemplo. Eu esmaguei o teclado.
Brandon Bertelsen
1

Parece-me que seria algo como

library(tutoR)
format(1.128347132904321674821, 2)

Por uma pequena ajuda online .

Tim Meers
fonte
Encontrei isso, mas requer um pacote, estou procurando algo dentro do pacote base.
Brandon Bertelsen
2
@brandon, format () faz parte da base. Abra R e digite? Formato ... não é necessário pacote.
JD Longo
Hrmmm, você olhou para o que isso gera? [1] "1.128347", caso contrário, você está certo sobre ele estar no pacote base, meu mal.
Brandon Bertelsen
1
Talvez tente format.default(x, digits = 2)apenas um tiro no escuro, com base no link fornecido. Essas informações são algumas das que faltam no que normalmente leio na documentação, esperava ver também as impressões.
Tim Meers
Só notei que seu link aponta para a documentação do tutoR, que não faz parte da base.
Brandon Bertelsen
1

se você quiser arredondar um número ou uma lista, basta usar

round(data, 2)

Em seguida, os dados serão arredondados para duas casas decimais.

jared
fonte