对于大量试验,`rbinom()`可能存在错误

时间:2014-10-07 16:49:33

标签: r random

我一直在编写一些代码,迭代地执行二项式绘制(使用rbinom),对于一些被调用者的参数,我最终可能会大到大,导致R(3.1.1,这两个官方或者自制软件构建测试 - 因此不太可能与编译器相关)返回意外的NA。例如:

rbinom(1,2^32,0.95)

是我期望的工作方式,但是会回复NA。但是,使用size=2^31prob≤0.5运行。

size < .Machine$integer.max为假时,使用精细的手册提到反转,这可能是问题吗?

3 个答案:

答案 0 :(得分:4)

查看the source rbinom对于如此大的尺寸执行以下等效(在C代码中):

qbinom(runif(n), size, prob, FALSE)

确实:

set.seed(42)
rbinom(1,2^31,0.95)
#[1] 2040095619
set.seed(42)
qbinom(runif(1), 2^31, 0.95, F)
#[1] 2040095619

然而:

set.seed(42)
rbinom(1,2^32,0.95)
#[1] NA
set.seed(42)
qbinom(runif(1), 2^32, 0.95, F)
#[1] 4080199349

@BenBolker指出rbinom返回一个整数,如果返回值大于.Machine$integer.max,例如,我的机器上大于2147483647,则返回NA 。相反,qbinom返回一个双精度数。我不知道为什么,似乎没有记录。

因此,似乎至少存在无证件行为,您应该报告它。

答案 1 :(得分:2)

我同意(在没有文件证明这是一个问题的情况下),这是一个错误。一个合理的解决方法是使用Normal近似,对于如此大的值,它应该非常非常好(并且更快)。 (我本来的意思是简短而简单,但结果有点失控。)

rbinom_safe <- function(n,size,prob,max.size=2^31) {
    maxlen <- max(length(size),length(prob),n)
    prob <- rep(prob,length.out=maxlen)
    size <- rep(size,length.out=maxlen)
    res <- numeric(n)
    bigvals <- size>max.size
    if (nbig <- sum(bigvals>0)) {
        m <- (size*prob)[bigvals]
        sd <- sqrt(size*prob*(1-prob))[bigvals]
        res[bigvals] <- round(rnorm(nbig,mean=m,sd=sd))
    }
    if (nbig<n) {
        res[!bigvals] <- rbinom(n-nbig,size[!bigvals],prob[!bigvals])
    }
    return(res)
}

set.seed(101)
size <- c(1,5,10,2^31,2^32)
rbinom_safe(5,size,prob=0.95)
rbinom_safe(5,3,prob=0.95)
rbinom_safe(5,2^32,prob=0.95)

当平均值远离0或1(以较近者为准)的许多标准差时,法线近似应该相当好。对于大N,这应该没问题,除非p 非常极端。例如:

n <- 2^31
p <- 0.95
m <- n*p
sd <- sqrt(n*p*(1-p))
set.seed(101)![enter image description here][1]
rr <- rbinom_safe(10000,n,prob=p)
hist(rr,freq=FALSE,col="gray",breaks=50)
curve(dnorm(x,mean=m,sd=sd),col=2,add=TRUE)
dd <- round(seq(m-5*sd,m+5*sd,length.out=101))
midpts <- (dd[-1]+dd[-length(dd)])/2
lines(midpts,c(diff(sapply(dd,pbinom,size=n,prob=p))/diff(dd)[1]),
      col="blue",lty=2)

enter image description here

答案 2 :(得分:2)

这是预期的行为,但有两个问题: 1)胁迫引起的NA应该发出警告 2)应记录离散随机变量具有存储模式整数的事实。

我已修复1)并将修改文档以修复2)当我有更多时间。