Generate integer random numbers from range (0:10^1

2019-02-16 06:18发布

问题:

I want to generate 10000 integer random numbers between 0 and 10^12. Usually, the code would look like this:

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

But I get following error message:

Error in 0:1000000000000 : result would be too long a vector

Is there a more memory efficient method that doesn't have to put 10^12 integers in a vector just to get a sample of size 10000? If not, is there a way to increase the max size of the vector? I'm working on a 64bit OS with 12GB of free RAM.

回答1:

The real problem lies in the fact that you cannot store the sequence of 0:10^12 into memory. By just defining 0 and 10^12 as boundaries of a uniform distribution, you could get what you seek:

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

This will draw from the uniform distribution (with replacement, though I doubt that matters).

However, what you cannot see is that these are actually floating numbers.

You can use ceiling to round them up:

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

So the full code would be:

ceiling(runif(10000, 0, 10^12))

Further nitpicking:

Note that this technically will not allow 0 to be there (since 0.0001 would be rounded up), so you could just draw from

ceiling(runif(10000, -1, 10^12))

As Carl Witthoft mentions, numbers that do not fit into the size of an integer will not be integers obviously, so you cannot count on these numbers to be integers. You can still count on them to evaluate to TRUE when compared to the same floating number without decimals though.



回答2:

I do not understand why you cannot just do...

sample(10^12,10,replace=TRUE)
#[1] 827013669653 233988208530 653034892160 564841068001 801391072663 683607493313
#[7] 254556497302 510154570389  51922126428 537709431414

If x has length 1, is numeric (in the sense of is.numeric) and x >= 1, sampling via sample takes place from 1:x.

N.B. This does not mean that sample has to generate the vector 1:x!! @James points out that for sampling of 0:x you will need to adjust to sample(10^12+1,10,replace=TRUE)-1



回答3:

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


回答4:

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

FYI: as.integer performs a truncation, not a rounding.

In order to test if it works you can try by generating numbers in a smaller interval (i.e. from 0 to 6) and visualize the histogram of the result to see if the result is a uniform distribution, i.e.

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


回答5:

The package extraDistr provides a range of additional probability distributions to sample from, including a discrete uniform distribution.

Random sampling with function rdunif works like other stats random sampling functions included with R like runif, and avoids needing to round as in other solutions:

> 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 ...