Управление количеством десятичных цифр при выводе на печать в R

110

В R есть опция для управления отображением цифр. Например:

options(digits=10)

Предполагается, что до конца R-сессии будет выдавать 10-значные результаты вычислений. В файле справки R определение параметра digits выглядит следующим образом:

digits: контролирует количество цифр для печати при печати числовых значений. Это всего лишь предложение. Допустимые значения: 1 ... 22, по умолчанию 7.

Итак, здесь говорится, что это только предложение. Что, если мне нравится всегда отображать 10 цифр, не больше и не меньше?

Мой второй вопрос: что, если мне нравится отображать более 22 цифр, то есть для более точных вычислений, например, 100 цифр? Возможно ли это с базовым R, или мне нужен дополнительный пакет / функция для этого?

Изменить: благодаря предложению jmoy я попробовал, sprintf("%.100f",pi)и он дал

[1] "3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000"

в котором 48 знаков после запятой. Это максимальный предел, с которым R может справиться?

Мехпер К. Палавузлар
источник
5
Только первые 15 цифр числа пи являются точными. Сравните с истинным значением joyofpi.com/pi.html
Ричи Коттон
1
Ты прав. Почему в R все по-другому?
Mehper C. Palavuzlar
4
См. FAQ на сайте R cran.r-project.org/doc/FAQ/…
Ричи Коттон,
2
Мехпер: Я думаю, что вы неверно истолковываете вычислительное представление чисел в R. Возможно, вы захотите прочитать en.wikipedia.org/wiki/Floating_point .
Шейн
Для сравнения, Python делает то же самое: Попробуйте python -c "import math; print(format(math.pi, '.100f'))". Результат - pi48 «реальных» десятичных знаков, заполненных нулями для оставшихся 52 цифр.
syntaxerror

Ответы:

49

Причина, по которой это всего лишь предположение, заключается в том, что вы можете легко написать функцию печати, которая игнорирует значение параметров. Встроенные функции печати и форматирования действительно используют optionsзначение по умолчанию.

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

Mathematica или Maple позволят вам указать столько десятичных знаков, сколько душе угодно.

РЕДАКТИРОВАТЬ:
Было бы полезно подумать о разнице между десятичными знаками и значащими цифрами. Если вы проводите статистические тесты, основанные на различиях, превышающих 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 для улучшения его точности? Или он может использовать только функции, закодированные внутри него?
skan
2
Я просто подумал: «Если вы проводите статистические тесты, основанные на различиях, превышающих 15-ю значащую цифру, то ваш анализ почти наверняка бесполезен». но мне было интересно, по какому количеству цифр я бы пришел к выводу, что это мусор, и я подумал, что 5, но я был бы рад поправиться.
PatrickT
46

Если вы сами производите весь вывод, вы можете использовать sprintf(), например,

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

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

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

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

Джйотирмой Бхаттачарья
источник
На самом деле, некоторые специальные тесты хи-квадрат, которые я применял, требовали сотен десятичных знаков, чтобы дать точные результаты. Также в пи есть тысячи десятичных знаков. Вот почему мне было интересно около 100 или более цифр.
Мехпер К. Палавузлар,
14
Пи имеет бесконечное количество десятичных знаков; это не значит, что компьютер может их хранить.
Шейн
Я полагаю, это сценарий, в котором Mathematica превосходит R.
skan
1
@skan Как вы думаете, в системе Mathematica хранится бесконечное количество десятичных знаков?
Грегор Томас
@Gregor, конечно, нет, но вы можете столько цифр, сколько позволяет ваша память.
skan
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основе каждого запроса времени, чтобы удовлетворить различные требования к десятичной печати.

Лэмпард
источник