Форматування десяткових місць у R


264

У мене є число, наприклад 1.128347132904321674821, яке я хотів би показати як два знаки після коми при виході на екран (або записаному у файл). Як це зробити?

x <- 1.128347132904321674821

Редагувати:

Використання:

options(digits=2)

Було запропоновано як можливу відповідь. Чи є спосіб вказати це в сценарії для одноразового використання? Коли я додаю його до свого сценарію, він, схоже, не робить нічого іншого, і мені не цікаво багато повторного введення для форматування кожного номера (я автоматизую дуже великий звіт).

-

Відповідь: кругла (x, цифри = 2)


1
Питання, пов’язані з цим: stackoverflow.com/questions/2287616/…
Шейн

Якщо ви використовуєте параметри (цифри = 4), це не обмежує обчислення чотирма цифрами, чи не так? У такому випадку це зробить програми набагато менш точними. Це ТІЛЬКО впливає на кількість при друкуванні, правильно?
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.з? опцій, це впливає лише на вихід.
Брендон Бертелсен

Зверніть увагу, що round(23, digits=2)буде надруковано, 23а не 23.00. Якщо ви хочете , останній, спробуйте stackoverflow.com/a/12135122/180892
Джеромі Anglim

4
@PaulHurleyuk, я думаю, що в програмуванні є хорошою практикою використовувати мінімально можливу кількість бібліотек. Хтось, хто використовує іншу бібліотеку для кожної тривіальної потреби, зазвичай стикається з безладом, великими файлами, проблемами переносимості тощо
Родріго

Відповіді:


381

Довідкова інформація : Деякі відповіді , запропоновані на цій сторінці (наприклад, signif, options(digits=...)) не гарантує , що певна кількість знаків після коми відображаються для довільного числа. Я припускаю, що це конструктивна особливість R, згідно з якою хороша наукова практика передбачає показ певної кількості цифр на основі принципів " значущих цифр ". Однак у багатьох областях (наприклад, стиль APA , ділові звіти) вимоги до форматування диктують певне число десяткових знаків. Це часто робиться для послідовності та стандартизації, а не стосується значних цифр.

Рішення :

Наступний код показує рівно два знаки після коми x.

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

Наприклад:

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"

Більш загальна функція полягає в наступному: де xє число і kкількість десяткових знаків для показу. trimwsвидаляє будь-який провідний пробіл, який може бути корисним, якщо у вас є вектор чисел.

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

Наприклад,

specify_decimal(1234, 5)
# [1] "1234.00000"
specify_decimal(0.1234, 5)
# [1] "0.12340"

4
+1 Лише відповідь, яка працювала на мене, правильно друкується 0.0001як0.00
ThomasH

7
Мене завжди непокоїть, як функції подобаються format()та prettyNum()перетворюють числові символи в символи. Як би ви вирішили це?
Вальдір Леонсіо

Що з цитатами, які з’являються?
F.Webber

2
@JeromyAnglim Зауважу, що вищевказане рішення має можливий недолік у певному випадку, коли фіксується кількість знаків перед десятковою, наприклад, format(c(10, 1), nsmall=1)вихідні показники "10.0" " 1.0"(зверніть увагу на провідний пробіл перед 1.0. Враховуючи те, що sprintf()функція, здається, гарантує кращі формати на обидві сторони десяткового знака, наприклад , sprintf(c(10,1), fmt = '%#.1f')позбавляється від цього неприємного ведучого простору і повертається "10.0" "1.0".
Ніколас G Reich

1
Провідні пробіли - це функція, призначена для вирівнювання десяткової крапки, коли результат formatвикористовується у стовпці.
мешканець

34

Ви можете відформатувати число, скажімо x, до десяткових знаків, як хочете. Ось xчисло з багатьма знаками після коми. Припустимо, ми хочемо показати до 8 знаків після коми цього числа:

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

Тут format="f"наводиться плаваючі числа у звичайних десяткових знаках, наприклад, xxx.xxx, і digitsвказується кількість цифр. На противагу цьому, якби ви хотіли отримати ціле число для відображення, ви б використовували format="d"(дуже подобається sprintf).


Хоча мені незрозуміло, що саме просила ОП, судячи з найвищої оцінки, я не міг не помітити, що formatCце майже виключно те, що я використовую для цього. Я вважаю, що ця відповідь є хорошою і знаходиться в базі R за запитом ОП.
AdamO

хтось із вас, хлопці, може допомогти на цьому? stackoverflow.com/q/53279593/5224236
gpier

24

Ви можете спробувати формат мого пакету .

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

Хороша річ, що xвсе-таки числовий вектор, і ви можете робити більше обчислень з тим же форматуванням.

> x + 1
[1] 2.13

Ще краще, що цифри не втрачаються, ви можете переформатувати більше цифр будь-коли :)

> formattable(x, digits = 6, format = "f")
[1] 1.128347

Така крихітна маленька колючка клопоче мене цілий ранок. Чомусь R закруглює дисплей лише для деяких стовпців. Мені знадобилося це виправлення, оскільки мені довелося виконувати обчислення і на цих стовпцях. Це працює. Дякую !
thethakuri

Мені подобається форматування, ніж будь-які функції baseR. Найбільшою перевагою вона зберігає змінну як числову.
Лазар Турстон

22

для 2 знаків після коми, якщо ви хочете зберегти проміжні нулі

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

що дає

[1] "5.50"

Як згадується @mpag нижче, схоже, що R іноді може давати несподівані значення за допомогою цього методу, наприклад, sprintf (5.5550, fmt = '% #. 2f') дає 5.55, а не 5.56


1
проте, хоча sprintf тури, sprintf (5.5550, fmt = '% #. 2f') дає дещо несподіваний результат: 5,55. sprintf (5.555000000001, fmt = '% #. 2f') дає 5.56. Це, мабуть, є загальним "питанням" із округленням у R, оскільки метод круглого, nsmall дає те саме.
mpag

Дякую @mpag, я поняття не мав, що R бореться з округленням кордонів, я просто спробував це з 5.565, що робить круглий вгору, а 5.545 раундів вниз. Я здогадуюсь, це так, як вони поводяться з точністю з плаваючою точкою. Я не думаю, що я бачив таку поведінку в інших мовах, що, напевно, означає, що вони мають вбудований спосіб вирішення
Марк Адамсон

Я вважаю, що вони навмисно ставляться до значень як обмежених за ступенем точності. Вони вважають, що значення, яке становить 5,555, насправді так само є ймовірним в результаті "реального" значення 5,5546, як 5,5554. Однак якщо продовжити подібну гру з округленням, 5.444445 може (неперевірено) закінчитися як "6", якщо робити це однозначно. Але ви можете мати рацію, що це може бути питання про те, що бінарне представлення трохи нижче 5,55.
mpag

Так, я думаю, якби це було навмисно, воно також було б узгоджене між 5.565 та 5.545. "Випадковість" підказує мені, що це річ із плаваючою точкою.
Марк Адамсон

хтось із вас, хлопці, може допомогти на цьому? stackoverflow.com/q/53279593/5224236
gpier

8

Щось схоже :

options(digits=2)

Визначення параметра цифр:

digits: controls the number of digits to print when printing numeric values.

Чи є спосіб встановити це динамічно під час запуску сценарію?
Брендон Бертелсен

Це працює для виведення в консоль R, але не працює в моєму сценарії (вони все ще виходять із .1289273982)
Брендон Бертелсен

1
Я маю дивну поведінку, digitsале, здається , цей варіант не встановлює кількість цифр після десяткової. Наприклад, коли я встановлюю параметри (цифри = 2), тоді друк 7,25 призводить до виходу 7,2, 1234,25 стає 1234, а 0,25 залишається 0,25. Чи є інший варіант взаємодії з цим?
Максим.К

8

Перевірте функції доситьNum, формат

використовувати пробні нулі (наприклад, 123.1240) sprintf(x, fmt='%#.4g')


@ 42 Я б закликав вчитися sprintf, це в основному рамки для форматування
jangorecki

1
@jangorecki Я не впевнений у вашій точці. Все, що я робив (ще 5 років тому), було запропонувати виправити правопис.
IRTFM

@ 42 Я жорстко ти скаржишся на fmtаргумент, вибач!
jangorecki

Я думаю, що ОП після фіксованих знаків після коми, а не фіксованих цифр. Здається, gу вашій відповіді є фіксовані цифри, які використовують fроботу краще.
Марк Адамсон

5

Якщо ви віддаєте перевагу значущим цифрам перед фіксованими цифрами, тоді може бути корисна команда signif :

> signif(1.12345, digits = 3)
[1] 1.12
> signif(12.12345, digits = 3)
[1] 12.1
> signif(12345.12345, digits = 3)
[1] 12300

1
Спасибі Пол. Ці двоє були не саме те, що я шукав, але означення привело мене до раунду (), що саме те, що мені потрібно. Ура,
Брендон Бертелсен

34
Error: could not find function "fixed"
ThomasH

signifпрацює для конкретного наданого числа, але я припускаю, що поширена застосовна проблема полягає в тому, коли потрібно вказати рівно два знаки після коми, але ви не знаєте, яке число випереджає час. У такому випадку signifбуде дано різну кількість десяткових знаків залежно від фактичної кількості.
Джеромі Англім

3
виправлений не зустрічається ніде. Виправте це, інакше цю оманливу відповідь слід видалити.
HelloWorld

@JeromyAnglim як ми можемо це виправити, коли хочемо 3sf? іноді це дає мені 3sf, інше 4sf і т. д. як це виправити?
christouandr7

4

Функцію formatC()можна використовувати для форматування числа до двох знаків після коми. Ця функція задається двома десятковими знаками, навіть якщо отримані значення включають проміжні нулі.


3

Я використовую цей варіант для примусового друку K десяткових знаків:

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

2

Зауважте, що числові об'єкти в R зберігаються з подвійною точністю , що дає вам (приблизно) 16 десяткових цифр точності - решта буде шумом. Я погоджуюсь, що наведене вище число, мабуть, є лише прикладом, але воно становить 22 цифри.


3
Підтверджено, це лише для прикладу. Я пюре клавіатури.
Брендон Бертелсен

1

Мені здається, це було б щось подібне

library(tutoR)
format(1.128347132904321674821, 2)

За невелику допомогу в Інтернеті .


Я знайшов це, але для нього потрібен пакет, я шукаю щось у базовому пакеті.
Брендон Бертелсен

2
@brandon, формат () є частиною бази. Відкрийте R і введіть? Формат ... не потрібні пакети.
JD Long

Хмммм, ти подивився, що це дає? [1] "1.128347" в іншому випадку, ви абсолютно праві, що він знаходиться в базовому пакеті, моє погано.
Брендон Бертелсен

1
Можливо, спробуйте format.default(x, digits = 2)лише постріл у темряві, хоча на основі наданого посилання. Ця інформація - це те, чого бракує тому, що я зазвичай читаю для документації, я також очікував побачити друковані виходи.
Тім Меерс

Щойно помітили, що ваше посилання вказує на документацію tutoR, яка не є частиною бази.
Брендон Бертелсен

1

якщо ви просто хочете округлити номер або список, просто скористайтеся

round(data, 2)

Тоді дані будуть круглими до 2 знаків після коми.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.