135

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

options(digits=10)

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

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

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

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

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

[1] "3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000"

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

4

3 回答 3

59

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

至于第二个问题,由于 R 使用有限精度算术,因此您的答案在小数点后 15 或 16 位后不准确,因此通常不需要更多。gmprcdd包处理多精度算术(通过与 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,但如果您遇到条件不佳的问题或不稳定的算法,它们可能会很有用。

于 2010-02-18T10:58:10.600 回答
54

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

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

指定您要格式化一个带十个小数点的浮点数(在%.10fisf中表示浮点数,而.10指定十个小数点)。

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

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

于 2010-02-18T10:49:03.607 回答
2

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

例如,如果您有一个向量,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根据每次查询来改变它,这样就可以满足不同的小数打印要求。

于 2020-02-27T21:56:48.063 回答