# [R] p-values < 2.2e-16 not reported

Will Eagle will.eagle at gmx.net
Thu May 20 18:16:09 CEST 2010

```> On 2010-05-20 08:52, Shi, Tao wrote:
>> Will,
>>
>>   I'm wondering if you have any
>> insights after looking at the cor.test source code.  It seems to be fine to me, as the p value is either calculated by "your first method" or a
>> .C code.
>>
>> ...Tao

Dear Tao,

I think the described problem of p-values < 2.2e-16 not being reported
(or set to zero, respectively) applies at least to the cor.test(,
method="pearson", alternative=c("greater","two.sided")) function, but
also other statistical test functions. You find the critical piece of
code with methods(cor.test) and getAnywhere(cor.test.default) in the
following lines:
...
p <- pt(STATISTIC, df) # line 27
...
PVAL <- switch(alternative,  # lines 144-145, reformatted
less = p,
greater = 1 - p,
two.sided = 2 * min(p, 1 - p))

This means that if you calculate a pearson correlation (which is the
default) with option alternativ="two.sided" (which is the default) or
alternative="greater", an additive operation of the 2nd kind is
performed, which causes that a very small p-value is set to zero. This
problem should not apply to alternative="less" since the p-value has
been generated without an additive operation with the pt() function.

What I still find confusing is that:

> pt(10,100,lower=FALSE)
[1] 4.950844e-17
> pt(10,100,lower=TRUE)   # should give 1 - 4.950844e-17
[1] 1
> 1-pt(10,100,lower=TRUE) # should give 4.950844e-17
[1] 0

So it seems that this distribution function(s) only give the exact value
if the option lower.tail=FALSE is used. Therefore, also cor.test(...,
method="pearson", alternative="less") might not report p-values <
2.2e-16. I find this behavior of R very unintuitive.

The .C code routines are by the way only used for methods=c("kendall",
"spearman") as far as I have seen.

Best, Will

```