我正在处理一个常规需要计算t分布密度的问题,而不是R中的尾部。
例如,使用R&t t t分布函数,dt(1.424781, 1486, -5)
返回[1] 2.75818e-10
。我的一些最终输出(使用此密度作为输入)与我的同事在MATLAB中执行的类似计算的参考值不匹配,我认为这可能是由于R中t分布的尾部不精确所致。 / p>
如果我与MATLAB的分布函数进行比较,nctpdf(1.424781, 1486, -5)
会返回ans = 4.3932e-10
,这与R的输出有很大的不同。
编辑:R打印两条相同的警告信息
In dt(1.424781, 1486, -5) : full precision may not have been achieved
in 'pnt{final}'
这是在Mac上,R版本3.3.1
答案 0 :(得分:4)
看起来问题来自于R为这种情况实现非中心t分布的算法。两个因素相结合产生结果:
从帮助文件的“注释”部分?pt
,
非零ncp的代码主要用于ncp的中等值:它不会高度准确,特别是在tails中,对于大值。
因此,计算这些值的算法并不是为了计算像-5这样的极值。我们可以通过将ncp值降低到更温和的水平来看到这一点,比如-1:
dt(1.424781, 1486, -1)
[1] 0.0211143
?pt
的来源部分说
对于基于
的C转换的pt的非中心情况Lenth,R。V.(1989)。算法AS 243 - 非中心t分布的累积分布函数,应用统计38,185-189。
这只计算下尾部,因此上部尾部会受到取消,并且当这可能很重要时会发出警告。
例如,相同的ncp值,-5与x值的负值返回
dt(-1.424781, 1486, -5)
[1] 0.0006719519
没有警告。
答案 1 :(得分:3)
您可以通过Rcpp使用Boost(可通过BH包获得)作为替代方案:
// [[Rcpp::depends(BH)]]
#include <Rcpp.h>
#include <boost/math/distributions/non_central_t.hpp>
using namespace boost::math;
// [[Rcpp::export]]
double dnct(const double x, const double df, const double ncp) {
non_central_t dist(df, ncp);
return pdf(dist, x);
}
/*** R
dnct(1.424781, 1486, -5)
*/
返回:
[1] 4.393078e-10
我不知道Boost或Matlab在这里是否更精确,但结果至少相似。增强文档提供了有关精度的一些信息。