我在R中生成一个小的随机统一数集合(在本例中为10,000),并且我以惊人的速度发现重复(例如,在10,000个数字抽奖中每隔几次重复一次).为什么会发生这种情况,我如何才能(有效地)阻止它?

下面是一个最小的工作示例,其中我继续并绘制了100万个Unif(0,1)值.这似乎会产生许多重复的值.我确实在寻找重复项时遇到了一些问题,所以我不得不在下面做了一些难看的事情,有时由于舍入或其他原因,这可能无法找到重复项,但它似乎在我的机器上起作用了.

rs_val <- .Random.seed 
tvals <- runif(10^6,0,1) 
tr1 <- as.numeric(names(which(table(tvals)>1)))[1] 
tr_idx <- which(abs(tvals-tr1)<0.000000001) 
tr_idx[1]
tr_idx[2]
format(tvals[tr_idx[1]],digits=22) 
format(tvals[tr_idx[2]],digits=22) 
tvals[tvals==as.numeric(format(tvals[tr_idx[1]],digits=22))]

对于一个现代的伪随机数生成器来说,大概100万次抽奖根本不应该是那么多,对吗?我在这里看到了一些关于C++的类似问题的帖子,但没有关于R的帖子.在R中,这与随机抽签发生得比随机种子重置更快或类似的事情有关.

有没有人可以对上面的代码进行有效的修改,以防止重复的随机数问题?基本上,我只是在长时间线上模拟泊松过程,这会导致同时发生事件,这是有问题的.我想,我可以只看一遍模拟,然后放弃重复的抽签,但如果不需要这样做就好了.

推荐答案

?Random人起:

不依赖于来自RNG的低位比特的随机性.大多数 提供的统一生成器返回32位整数值,这些值是 转换为双精度,因此它们最多采用2^32个不同的值,并且 长运行将返回重复的值(Wichmann-Hill是 例外,并且都至少提供30个不同的位.)

这一点很容易验证:

identical(min(diff(unique(sort(runif(1e6))))), 2^-32)
#> [1] TRUE
sum((runif(1e6) %% 2^-32))
#> [1] 0

因此,除了使用Wichmann-Hill外,另一个 Select 是在不替换的情况下采样1:(2^32 - 1),并除以2^32,尽管这不如使用Wichmann-Hill的runif表现.

system.time(x <- sample(2^32 - 1, 1e6)/2^32)
#>    user  system elapsed 
#>    0.16    0.01    0.17
RNGkind(kind="Wichmann-Hill")
system.time(x <- runif(1e6))
#>    user  system elapsed 
#>    0.04    0.00    0.05

第二种 Select 是调用runif两次:一次用于32位精度,第二次用于填补空白以使其精度加倍:

RNGkind(kind="default")

runif64 <- function(n) runif(n) + runif(n, -2^-33, 2^-32 - 2^-33)
x <- runif64(1e6)
range(x)
#> [1] 4.710828e-07 9.999975e-01
anyDuplicated(x)
#> [1] 0

runif64的速度大约是直接拨打runif的两倍.

microbenchmark::microbenchmark(
  runif64(1e6),
  runif(1e6)
)
#> Unit: milliseconds
#>            expr     min       lq     mean median       uq      max neval
#>  runif64(1e+06) 61.1622 63.33880 65.91086 64.926 67.18855 109.3689   100
#>    runif(1e+06) 29.7481 30.34125 31.91007 30.997 33.71515  40.3735   100

2^64个可能值的1e6个样本中看到任何重复值的概率非常小:

library(Rmpfr)

n <- mpfr(2^64, 128)
m <- mpfr(1e6, 128)
as.numeric(1 - exp(lgamma(n + 1) - m*log(n) - lgamma(n - m + 1)))
#> [1] 2.710503e-08

R相关问答推荐

修改dDeliverr中列表列的最后一个元素

替换字符的所有实例,但仅限于匹配字符串中

返回句子中最长的偶数长单词

强制相关图以显示相关矩阵图中的尾随零

从API中抓取R数据SON

x[[1]]中的错误:脚注越界

R:更新后无法运行控制台

在R中替换函数中的特定符号

用黄土法确定区间

在另存为PNG之前隐藏htmlwidget绘图元素

从BRM预测价值

用约翰逊分布进行均值比较

将选定的索引范围与阈值进行比较

将多个变量组合成宽格式

在gggraph中显示来自不同数据帧的单个值

如何合并不同列表中的数据文件,包括基于名称的部分匹配,而不是一对一等价

替换在以前工作的代码中有x行&q;错误(geom_sf/gganimate/dow_mark)

使用LAG和dplyr执行计算,以便按行和按组迭代

基于R中的引用将向量值替换为数据框列的值

conditionPanel不考虑以下条件