从范围(0:10^12)生成整数随机数

26

我希望生成一万个介于0和10^12之间的整数随机数。 通常情况下,代码看起来是这样的:

x <- sample(0:1000000000000,10000,replace=T)

但是我收到以下错误信息:
Error in 0:1000000000000 : result would be too long a vector

有没有更节省内存的方法,不需要将10 ^ 12个整数放入向量中,仅获取大小为10000的样本? 如果没有,是否有一种增加向量最大大小的方法?我正在使用具有12GB可用RAM的64位操作系统。


1
它们需要是唯一的吗? - nanofarad
1
你估计过一个包含10^12个元素的向量所需的内存吗?12GB是不够的。 - knivil
1
你为什么需要这么大的范围?实际上,你所要求的是具有12位精度的均匀随机样本,我无法理解需要这种精细程度的原因。 - Carl Witthoft
5个回答

34

真正的问题在于你无法将0到10^12的序列存储在内存中。只需将0和10^12定义为均匀分布的边界,你就可以得到你要找的内容:

runif(10000, 0, 10^12)
[1] 136086417828 280099797063 747063538991 250189170474 589044594904
[6]  65385828028 361086657969 186271687970 338900779840 649082854623  ........

这将从均匀分布中进行抽样(带替换,虽然我不认为这很重要)。

不过,你看不到的是这些实际上是浮点数。

你可以使用 ceiling 将它们四舍五入:

samp = runif(1, 0, 10^12)
samp
[1] 19199806033
samp == 19199806033
[1] FALSE
ceiling(samp) == 19199806033
[1] TRUE

因此完整的代码将是:

ceiling(runif(10000, 0, 10^12))
进一步的挑剔:
请注意,严格来说这不允许0存在(因为0.0001会被四舍五入),所以你可以从中选择。
ceiling(runif(10000, -1, 10^12))

正如Carl Witthoft提到的那样,超出整数大小范围的数字显然不会是整数,因此您不能指望这些数字是整数。但是,当与没有小数的相同浮点数进行比较时,您仍然可以指望它们评估为TRUE


1
除了那些不是整数,因为 2^31 < 10^12。它们仍然是浮点数,如果不小心可能会遇到舍入误差。 - Carl Witthoft
1
is.integer(ceiling(10^11)) [1] FALSE。根据计算机的理解,没有小数部分的 float 并不是一个integer - Carl Witthoft
我现在明白了,不能适应整数空间的数字显然无法转换为整数。 - PascalVKooten
请记住,在几乎所有编程语言中,整数都被限制在2^31以内(除非您在C语言中调用long_int之类的类型)。这一点非常重要,因为整数可以被精确地存储,但浮点数则是以二进制等价物中的尾数和指数存储的,这些值是不精确的。 - Carl Witthoft
1
你仍然可以使用双精度浮点数准确地表示整数值,最高可达2^53,接近10^16。 - James
显示剩余3条评论

23

我不明白为什么你不能只是做...

sample(10^12,10,replace=TRUE)
#[1] 827013669653 233988208530 653034892160 564841068001 801391072663 683607493313
#[7] 254556497302 510154570389  51922126428 537709431414
如果x的长度为1,且在is.numeric的意义下是数值型的,而且x >= 1,则使用sample函数时会从1:x中进行抽样。
注意,这并不意味着sample一定会生成向量1:x!!@James指出,如果要对0:x进行抽样,则需要调整为sample(10^12+1,10,replace=TRUE)-1

1
非常正确...先草率地拼凑出一个答案,再去思考,这样做的效果不会太好。 - PascalVKooten
现在不包括0。 - PascalVKooten
3
sample(10^12+1,10,replace=TRUE)-1 - James
真的吗?比使用“ceiling”函数更高效? - Simon O'Hanlon
2
完全不重要你是否在可能性向量中包含零,因为即使有它的概率也只有10^(-12)! - Ben Bolker
@BenBolker 但是“我相信我的特殊数字会赢得Powerball” :-) - Carl Witthoft

1
floor(runif(10000,min=0,max=(10^12)))

1
10^12永远不会被返回。 - Marco Demaio

1
as.integer(runif(10000, min = 0, max = (1 + 10^12)))

请注意:函数as.integer执行的是截断而非四舍五入。

为了测试其有效性,您可以尝试在较小的区间内生成数字(例如从0到6),并可视化结果的直方图,以验证结果是否呈均匀分布,即:

test <- as.integer(runif(10000, min = 0, max = (6 + 1)))
hist(test)

我正在寻找类似的想法... 我使用了 m <- as.integer(runif(10000, min = 0, max = (1 + 10^12))) 但是发现出现了 NAs introduced by coercion to integer range 的错误,因此请谨慎使用。而 m <- ceiling(runif(10000, -1, 10^12)) 则没有产生 NAs。 - mccurcio

0

extraDistr提供了一系列额外的概率分布进行随机抽样,包括离散均匀分布

使用函数rdunif进行随机抽样的方式与R中包含的其他stats随机抽样函数(如runif)类似,并且避免了像其他解决方案中一样需要四舍五入的问题:

> library("extraDistr")
> rdunif(n = 10000, min = 0, max = 10^12)
[1] 699559531175 881392957410 315869810758 941600866616
[5] 906084092567 681591022527 514061764115 122652820777
[9] 583204373950 517842726316 741211620393 422150962055 ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接