Контролюючи число десяткових цифр у виводі друку в R


110

Існує опція R, щоб отримати контроль над цифровим відображенням. Наприклад:

options(digits=10)

повинен дати результати обчислення в 10 цифрах до кінця R сесії. У довідковому файлі R визначення параметра цифр таке:

цифр: керує кількістю цифр для друку під час друку числових значень. Це лише пропозиція. Дійсні значення - 1 ... 22, за замовчуванням - 7

Отже, він говорить, що це лише пропозиція. Що робити, якщо мені подобається завжди відображати 10 цифр, не більше чи менше?

Друге моє питання: що робити, якщо мені подобається відображати більше 22 цифр, тобто для більш точних обчислень, таких як 100 цифр? Це можливо з базовою R або мені потрібен додатковий пакет / функція для цього?

Редагувати: Завдяки пропозиції jmoy, я спробував, sprintf("%.100f",pi)і це дало

[1] "3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000"

який має 48 десятків. Це максимальна межа R, яку можна впоратися?


5
Точні лише перші 15 цифр пі. Порівняйте з справжньою цінністю joyofpi.com/pi.html
Річі Коттон

1
Ти маєш рацію. Чому він різний у R?
Мехпер К. Палавузлар

4
Дивіться поширені запитання про R cran.r-project.org/doc/FAQ/…
Річі Коттон,

2
Мехпер: Я думаю, що ви неправильно трактуєте обчислювальне представлення чисел у Р. Ви можете прочитати en.wikipedia.org/wiki/Floating_point .
Шейн

Для порівняння, Python робить точно так само: Спробуйте python -c "import math; print(format(math.pi, '.100f'))". Результат - pi48 "справжніх" десяткових знаків, заповнені нулями для решти 52 цифри.
синтаксичний помилок

Відповіді:


49

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

Щодо другого питання, оскільки R використовує арифметику з обмеженою точністю, то ваші відповіді не точні за 15 чи 16 знаків після коми, тому загалом більше нічого не потрібно. В GMP і RCDD пакети справу з декількома прецизійного арифметиці (через interace в бібліотеку ГМП), але це в основному пов'язано з великими цілими числами , а не більше десяткових знаків для ваших двійників.

Математика або Клен дозволять вам дати стільки десяткових знаків, скільки бажає ваше серце.

EDIT:
Може бути корисним подумати про різницю між десятковими знаками та значущими цифрами. Якщо ви робите статистичні тести, які розраховують на відмінності, що перевищують 15-ту значущу цифру, то ваш аналіз майже напевно є непотрібним.

З іншого боку, якщо ви просто маєте справу з дуже маленькими числами, це менше проблеми, оскільки R може обробляти число таким же малим, як .Machine$double.xminправило (2e-308).

Порівняйте ці два аналізи.

x1 <- rnorm(50, 1, 1e-15)
y1 <- rnorm(50, 1 + 1e-15, 1e-15)
t.test(x1, y1)  #Should throw an error

x2 <- rnorm(50, 0, 1e-15)
y2 <- rnorm(50, 1e-15, 1e-15)
t.test(x2, y2)  #ok

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


Як зазначає e3bo, ви можете використовувати багатоточні номери з плаваючою комою за допомогою Rmpfrпакета.

mpfr("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825")

Це більш повільні та більш оперативні в пам'яті, ніж звичайні (подвійні точності) numericвектори, але можуть бути корисними, якщо у вас погано обумовлена ​​проблема або нестабільний алгоритм.


4
Як ця сторінка Rwiki демонструє, то пакет Rmpfr дозволяє з високою точністю з плаваючою точкою арифметики в R.
e3bo

Але чи може Rmpfr використовувати будь-який пакет R для підвищення його точності? Або він може використовувати лише функції, закодовані всередині нього?
скан

2
Я думав просто так: "Якщо ви робите статистичні тести, які розраховують на відмінності, що перевищують 15-ту значущу цифру, то ваш аналіз майже напевно є непотрібним". але я задумався, якою буде кількість цифр, за якою я б зробив висновок, що це сміття, і я подумав 5, але буду радий виправитись.
PatrickT

46

Якщо ви виробляєте весь вихід самостійно, ви можете використовувати sprintf(), наприклад,

> sprintf("%.10f",0.25)
[1] "0.2500000000"

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

Я не знаю жодного способу змусити функції вищого рівня R надрукувати точну кількість цифр.

Відображення 100 цифр не має сенсу, якщо ви друкуєте звичайні цифри R, оскільки найкраща точність, яку ви можете отримати, використовуючи 64-розрядні подвійні цифри, - це приблизно 16 десяткових цифр (подивіться .Machine $ double.eps у вашій системі). Решта цифр будуть просто непотрібними.


Власне, для якихось спеціальних тестів на чи-квадрат, які я застосував, були потрібні сотні десятків, щоб дати точні результати. Також пі має тисячі десяткових знаків. Ось чому мені було цікаво близько 100 і більше цифр.
Мехпер К. Палавузлар

14
pi має нескінченну кількість десяткових знаків; це не означає, що комп'ютер може зберігати їх.
Шейн

Я думаю, що це сценарій, коли Mathematica перевершує R.
скан

1
@skan Ви думаєте, що Mathematica зберігає нескінченну кількість десятків?
Грегор Томас

@ Грегор, звичайно, ні, але ви можете мати стільки цифр, скільки дозволяє пам'ять.
скан

1

Ще одне рішення, здатне керувати кількістю десяткових цифр для друку на основі потреб (якщо ви не хочете друкувати надлишкові нулі)

Наприклад, якщо у вас є векторний такий, elementsякий ви хочете отримати sumз нього

elements <- c(-1e-05, -2e-04, -3e-03, -4e-02, -5e-01, -6e+00, -7e+01, -8e+02)
sum(elements)
## -876.5432

Мабуть, останній цифровий, як 1усічений, ідеальним результатом повинен бути -876.54321, але якщо він встановлений як фіксований десятковий параметр друку, наприклад sprintf("%.10f", sum(elements)), надмірний нуль (и) генерують як-876.5432100000

Виконуючи підручник тут: друк десяткових чисел , якщо ви зможете визначити, скільки десяткових цифр у певному числовому числі, як тут у -876.54321, потрібно надрукувати 5 десяткових цифр, то ми можемо встановити параметр для formatфункції, як показано нижче:

decimal_length <- 5
formatC(sum(elements), format = "f", digits = decimal_length)
## -876.54321

Ми можемо змінювати на decimal_lengthоснові кожного запиту, щоб він міг задовольнити різні вимоги до друку у десятковій кількості.

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