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)



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"

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).


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

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


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.

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')


@ 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

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.


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)

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.


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 .


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.