I am trying to generate random numbers in the range from 0 to 99 using a function rcoin
that returns 0 or 1 with equal probability. I have written the following code that converts a binary number generated from successive calls of rcoin
function, and then returns it with the condition that the number is less than 100. Here is the R code.
rcoin <- function() {
rbinom(n = 1, size = 1, prob = 0.5)
}
r100 <- function(n=100) {
v = n + 1
while(v > n) {
v = sum(sapply(0:6, function(i) rcoin() * 2 ^ i))
}
v
}
val_plot <- function() {
N = 10000
rand_sample <- rep(0, N)
for (i in 1:N){
rand_sample[i] = r100()
}
hist(rand_sample, breaks = 100)
}
val_plot()
It is supposed to produce uniform random numbers from 0 to 99, as truncated uniform distribution is also uniform. But when I plot the histogram of 10000 generated values, I see the value 0 is generated for unusually large number of times, but all other values follow a uniform distribution. Why? I guess this is because the binary number "1111111" is getting rejected whereas "0000000" is not. But how do I solve this issue? Is there any way to improve it?
This comes down to an issue with the usage of hist
, not the function itself.
To resolve:
1) replace while(v > n) {
with while(v >= n) {
so we generate numbers below 100 and reject numbers 100 or higher. Otherwise the output of r100
will range from 0 to 100, not 0 to 99.
2) replace hist(rand_sample, breaks = 100)
with hist(rand_sample, breaks = 0:100, right = F)
. Otherwise, the default hist
settings will bin the 0's and 1's and make the first bin look too big.
We can see this behavior from a simple built-in uniform distribution, too.
hist(floor(runif(1E6, min = 0, max = 100)), breaks = 100)
hist(floor(runif(1E6, min = 0, max = 100)), breaks = 0:100, right = F)