控制R中打印输出中的小数位数

Posted

技术标签:

【中文标题】控制R中打印输出中的小数位数【英文标题】:Controlling number of decimal digits in print output in R 【发布时间】:2011-01-18 06:14:09 【问题描述】:

R 中有一个选项可以控制数字显示。例如:

options(digits=10)

应该以 10 位数字给出计算结果,直到 R 会话结束。在R的帮助文件中,digits参数的定义如下:

digits:控制位数 打印数值时打印。 这只是一个建议。有效值 为 1...22,默认为 7

所以,它说这只是一个建议。如果我喜欢始终显示 10 个数字,而不是更多或更少,该怎么办?

我的第二个问题是,如果我想显示超过 22 位数字,即更精确的计算,如 100 位数字,该怎么办?是否可以使用基本 R,或者我需要额外的包/功能吗?

编辑:感谢jmoy的建议,我尝试了sprintf("%.100f",pi),它给了

[1] "3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000"

有 48 位小数。这是R可以处理的最大限制吗?

【问题讨论】:

只有 pi 的前 15 位数字是准确的。对比真值joyofpi.com/pi.html 你是对的。为什么它在 R 中有所不同? 请参阅 R cran.r-project.org/doc/FAQ/… 上的常见问题解答 Mehper:我认为您误解了 R 中数字的计算表示。您可能需要阅读 en.wikipedia.org/wiki/Floating_point。 作为比较,Python 做的完全一样:试试python -c "import math; print(format(math.pi, '.100f'))"。结果是pi,有 48 个“真实”小数,其余 52 位用零填充。 【参考方案1】:

它只是一个建议的原因是您可以很容易地编写一个忽略选项值的打印函数。内置的打印和格式化功能默认使用options 值。

关于第二个问题,由于 R 使用有限精度算术,因此您的答案在小数点后 15 或 16 位后不准确,因此通常不需要更多。 gmp 和 rcdd 包处理多精度算术(通过与 gmp 库的接口),但这主要与大整数有关,而不是双精度数的更多小数位。

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 向量相比,这些向量使用起来更慢且占用更多内存,但如果您遇到条件不佳的问题或不稳定的算法,它们会很有用。

【讨论】:

正如this Rwiki page 所展示的,Rmpfr package 允许在 R 中进行高精度浮点运算。 但是任何 R 包都可以使用 Rmpfr 来提高其精度吗?还是只能使用内部编码的功能? 我只是在想,“如果你正在做的统计测试依赖于超过 15 位有效数字的差异,那么你的分析几乎肯定是垃圾。”但我想知道我会断定它是垃圾的位数是多少,我想是 5,但我很乐意接受纠正。【参考方案2】:

如果您自己生成整个输出,则可以使用sprintf(),例如

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

指定您要格式化带有十个小数点的浮点数(在%.10f 中,f 用于浮点数,.10 指定十个小数点)。

我不知道有什么方法可以强制 R 的高级函数打印确切的位数。

如果您打印 R 的常用数字,则显示 100 位数字没有意义,因为使用 64 位双精度可以获得的最佳精度约为 16 位十进制数字(查看系统上的 .Machine$double.eps)。剩下的数字就是垃圾。

【讨论】:

实际上,我应用的一些特殊卡方检验需要数百位小数才能得出准确的结果。 pi 也有数千位小数。这就是为什么我想知道大约 100 位或更多数字。 pi 有无限个小数;这并不意味着计算机可以存储它们。 我猜这是 Mathematica 优于 R 的场景。 @skan 你认为 Mathematica 存储了无限个小数吗? @Gregor 当然不是,但是您可以根据记忆的数量来选择多少位数。【参考方案3】:

另一种解决方案能够根据需要控制要打印多少个十进制数字(如果您不想打印多余的零)

例如,如果您有一个向量为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

按照这里的教程:printing decimal numbers,如果能识别出某个数字有多少个十进制数字,比如这里-876.54321,有5个十进制数字需要打印,那么我们可以设置一个参数format函数如下:

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

我们可以根据每次查询更改decimal_length,从而满足不同的十进制打印要求。

【讨论】:

以上是关于控制R中打印输出中的小数位数的主要内容,如果未能解决你的问题,请参考以下文章

Python:format函数控制输出的小数点位数

c语言如何控制小数位数?

c++中如何精确输出的位数?

c语言如何控制小数位数

C语言中输出时怎样控制小数点后的位数,请举例说明保留1、2、3、4位小数等等,谢谢

C语言中输出时怎样控制小数点后的位数,请举例说明保留1、2、3、4位小数等等,谢谢