2

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?

  • 1
    I haven't cracked it completely but I think it's a problem with the use of `hist` and not a property of your function. Try replacing `hist(rand_sample, breaks = 100)` with `table(rand_sample)` to see a tabular output. I see no spike in 0's there, but you'll note it includes outputs with 100. To fix that, you can replace `while(v > n) {` with `while(v >= n) {` so that values of 100 are rejected. – Jon Spring Dec 28 '19 at 04:08

1 Answers1

6

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)

enter image description here

hist(floor(runif(1E6, min = 0, max = 100)), breaks = 0:100, right = F)

enter image description here

Jon Spring
  • 28,537
  • 3
  • 24
  • 43