提问人:Mehper C. Palavuzlar 提问时间:2/18/2010 最后编辑:zx8754Mehper C. Palavuzlar 更新时间:3/24/2022 访问量:314684
在 R 中控制打印输出中的十进制位数
Controlling number of decimal digits in print output in R
问:
R 中有一个选项可以控制数字显示。例如:
options(digits=10)
应该以 10 位数字给出计算结果,直到 R 会话结束。在 R 的帮助文件中,digits 参数的定义如下:
位数:控制位数 打印数值时进行打印。 这只是一个建议。有效值 是 1...22,默认值为 7
所以,它说这只是一个建议。如果我喜欢始终显示 10 位数字,而不是多或少,该怎么办?
我的第二个问题是,如果我喜欢显示超过 22 位数字,即像 100 位数字这样更精确的计算怎么办?基本 R 是否可以使用,或者我需要额外的包/功能?
编辑:多亏了 jmoy 的建议,我尝试了,它给了sprintf("%.100f",pi)
[1] "3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000"
它有 48 位小数。这是 R 可以处理的最大限制吗?
答:
如果您自己生成整个输出,则可以使用 ,例如sprintf()
> sprintf("%.10f",0.25)
[1] "0.2500000000"
指定要用 10 个小数点设置浮点数的格式(在 is 中表示浮点数,指定 10 个小数点)。%.10f
f
.10
我不知道有什么方法可以强制 R 的高级函数打印确切的数字数。
如果要打印 R 的常用数字,则显示 100 位数字是没有意义的,因为使用 64 位双精度可以获得的最佳精度约为 16 位十进制数字(查看 .机器$double.eps)。剩下的数字将只是垃圾。
评论
它只是一个建议的原因是,你可以很容易地编写一个忽略选项值的打印函数。内置的打印和格式设置功能确实使用该值作为默认值。options
至于第二个问题,由于 R 使用有限精度算术,因此您的答案在小数点后 15 或 16 位以上不准确,因此通常不需要更多。gmp 和 rcdd 软件包处理多精度算术(通过 gmp 库的接口),但这主要与大整数有关,而不是双精度的小数位。
Mathematica 或 Maple 将允许您根据自己的意愿给出任意数量的小数位。
编辑:
考虑小数位和有效数字之间的区别可能会有所帮助。如果你正在做统计检验,依赖于超过15个有效数字的差异,那么你的分析几乎可以肯定是垃圾。
另一方面,如果你只处理非常小的数字,那就不成问题了,因为 R 可以处理小到(通常是 2e-308)的数字。.Machine$double.xmin
比较这两个分析。
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
评论
另一种解决方案能够根据需要控制要打印的十进制数字数(如果您不想打印冗余零)
例如,如果你有一个向量,并且想得到它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
按照这里的教程:打印十进制数,如果能够识别出某个数字中有多少个十进制数字,就像这里一样,有5个十进制数字需要打印,那么我们可以为函数设置一个参数,如下所示:-876.54321
format
decimal_length <- 5
formatC(sum(elements), format = "f", digits = decimal_length)
## -876.54321
我们可以根据每次查询进行更改,因此可以满足不同的十进制打印要求。decimal_length
如果您主要使用 s,则有一个强制使用数字的函数:.tibble
num()
下面是一个示例:
library(tidyverse)
data <- tribble(
~ weight, ~ weight_selfreport,
81.5,81.66969147005445,
72.6,72.59528130671505,
92.9,93.01270417422867,
79.4,79.4010889292196,
94.6,96.64246823956442,
80.2,79.4010889292196,
116.2,113.43012704174228,
95.4,95.73502722323049,
99.5,99.8185117967332
)
data <-
data %>%
mutate(across(where(is.numeric), ~ num(., digits = 3)))
data
#> # A tibble: 9 × 2
#> weight weight_selfreport
#> <num:.3!> <num:.3!>
#> 1 81.500 81.670
#> 2 72.600 72.595
#> 3 92.900 93.013
#> 4 79.400 79.401
#> 5 94.600 96.642
#> 6 80.200 79.401
#> 7 116.200 113.430
#> 8 95.400 95.735
#> 9 99.500 99.819
因此,您甚至可以根据自己的需要决定使用不同的舍入选项。我发现它非常有用,并且是打印 dfs 的相当快速的解决方案。
评论
python -c "import math; print(format(math.pi, '.100f'))"
pi