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


110

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可以处理的最大限制吗?


5
pi的仅前15位数字是正确的。比较真实值joyofpi.com/pi.html
Richie Cotton

1
你是对的。为什么在R中有所不同?
Mehper C. Palavuzlar


2
Mehper:我认为您误解了R中数字的计算表示形式。您可能需要阅读en.wikipedia.org/wiki/Floating_point
Shane 2010年

作为比较,Python的功能完全相同:Try python -c "import math; print(format(math.pi, '.100f'))"。结果是pi48个“实际”小数,其余52位用零填充。
语法错误,2015年

Answers:


49

这只是一个建议,原因是您可以很容易地编写一个忽略选项值的打印功能。内置的打印和格式化功能确实使用该options值作为默认值。

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

MathematicaMaple可以让您随心所欲地赋予小数位数。

编辑:
考虑小数位和有效数字之间的差异可能很有用。如果您进行的统计检验依赖于第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封装允许在高河精度浮点运算
e3bo

但是Rmpfr可以被任何R软件包用来提高其精度吗?还是只能使用内部编码的功能?
skan

2
我当时只是在想:“如果您进行的统计检验依赖于第15位有效数字以外的差异,那么您的分析几乎肯定是垃圾。” 但是我想知道我得出的结论是多少位数,我想是5,但我很乐意接受纠正。
PatrickT

46

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

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

要格式化十个小数点浮点数(在指定%.10ff是浮动和.10指定十位十进制点)。

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

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


实际上,我应用的一些特殊的卡方检验需要数百位小数才能得出准确的结果。pi也有数千个小数。这就是为什么我想知道大约100个或更多数字的原因。
Mehper C. Palavuzlar

14
pi有无限数量的小数;这并不意味着计算机可以存储它们。
Shane 2010年

我想这是一个场景,其中数学是优于R.
SKAN

1
@skan您认为Mathematica存储无限数量的小数吗?
Gregor Thomas

@Gregor当然不会,但是您可以根据记忆允许的位数。
skan 2015年

1

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

例如,如果您有一个向量as 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根据每次查询更改,因此可以满足不同的十进制打印要求。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.