关于简单的看似无辜的函数的简单问题:summary
。
直到我看到min和max的结果超出了我的数据范围,我才意识到summary
有一个指定输出结果精度的参数。我的问题是如何以一种干净、普遍的方式来解决这个问题。
以下是问题的一个例子:
set.seed(0)
vals <- 1 + 10 * 1:50000
df <- cbind(rnorm(10000),sample(vals, 10000), runif(10000))
应用
digits
和
summary
,我们得到以下输出-注意范围值与最小值和最大值之间的差异:
> apply(df, 2, summary)
[,1] [,2] [,3]
Min. -3.703000 11 6.791e-05
1st Qu. -0.668500 122800 2.498e-01
Median 0.009778 248000 5.014e-01
Mean 0.010450 248800 5.001e-01
3rd Qu. 0.688800 374000 7.502e-01
Max. 3.568000 499900 9.999e-01
> apply(df, 2, range)
[,1] [,2] [,3]
[1,] -3.703236 11 6.790622e-05
[2,] 3.568101 499931 9.998686e-01
在
range
中看到错误的范围有点令人不安,所以我查看了
summary
选项,但这只是格式化输出的标准符号。另外请注意:除Min以外的每一个分位数都显示了数据集中不存在的值(这就是为什么我在
digits
的定义中放置了一个
1 +
),在大多数标准分位数计算中也看不到这些分位数,甚至考虑到中点选择的差异。(当我在原始数据中看到这一点时,我想知道我是如何从所有东西中损失了1的值!)
可解释的计算行为(即格式和精度)和统计激励的期望(例如,被识别为分位数的值实际上在数据集的范围内)之间存在差异。因为我们不能改变期望,所以我们需要改变代码的行为,或者至少改进它。
问题:是否有更合适的方法来设置输出以确保范围,而不是将其设置为大值,例如
vals
?16是最合适的普遍违约吗?使用16位似乎是双浮点数精度的最佳保证,尽管看起来输出实际上不会有16位(输出似乎仍然被截断为8或9位)。
更新1:正如@briandiggs所指出的,通过链接,行为被记录下来,但出乎意料。为了澄清我的问题,相对于Brian提供的链接上的答案(Brian自己提供的答案除外):这并不是行为没有文档记录,但是将其表示为最小值和最大值(不是最小值和最大值)是完全错误的。一个文档化的函数在其默认设置需要与非默认设置一起使用(或不应使用)。(也许有人会争论“最小值”和“最大值”是否应该重命名为“近似最小值”和“近似最大值”,但我们不去那里。)
更新2:正如@dwin所指出的,
digits = 16
将其作为默认值。我以前说违约率是3是错误的。有趣的是,这意味着有两种方法可以设置输出的行为。如果我们同时使用这两种方法,行为就会变得奇怪:
> options(digits = 20)
> apply(df, 2, summary, digits = 10)
[,1] [,2] [,3]
Min. -3.7032358429999998605808 11.00000000000000 6.7906221370000004927e-05
1st Qu. -0.6684710537000000396546 122798.50000000000000 2.4977348059999998631e-01
Median 0.0097783099960000001427 247971.00000000000000 5.0137970539999998643e-01
Mean 0.0104475229200000005458 248776.38699999998789 5.0011818200000002221e-01
3rd Qu. 0.6887842181000000119084 374031.00000000000000 7.5024240300000000214e-01
Max. 3.5681007909999999938577 499931.00000000000000 9.9986864070000003313e-01
注意,现在它有20位数的输出,即使传递的参数指定了10位数的精度。如果我们将数字的全局选项设置为一些“正常”值(如16),那么如果我们为
summary()
提供一个参数10,那么最终还是会出现问题。
我相信文档是不完整的,BrianDiggs在R-Help链接中的深思熟虑的回答中指出了与此相关的其他问题。
尽管有了这些皱纹,这个问题仍然悬而未决,但也许无法回答。我怀疑最好的结果就是保持全局数字选项不变(尽管我对上述行为的影响有点不安),而是将值16传递给
max(3, getOption("digits") - 3)
。在指定输出精度的地方并不是很明显,但是这4个值的交互作用-全局选项(和全局选项-3)、传递值和在
summary
中硬编码的值12看起来像是一个黑客(宽恕我的灵魂吧)。
更新3:我接受了德温的回答——这让我了解了这种香肠是如何制作的。看到正在发生的事情,我认为没有一种方法可以做到我所要求的,而不需要重写
summary
。
我是一名优秀的程序员,十分优秀!