Search code examples
rconditional-statementsrepeat

Generate random values in array until a total value is reached in R


I want to create an array, then assign a value to each place until the sum of values in the array equals a given total. Once the maximum value is reached the rest of the array can be 0. So to start:

years <- 20 # total length of array

N <- array(0, years) # make array

tot <- 10 # Total I want to stop at

max.size <- 3 # maximum value to put in the array

So the result may look something like: N = c(1,3,0,2,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0)

I think a while statement would work, similar to this question, but not sure how to get there. Also, I think this question has the pieces I need, but am struggling to put them into my context.

random.sample <- function(x) {  repeat {
# do something
i <- sample(0:max.size, 1)
x <- i
# exit if the condition is met
if (sum(x) == tot) break } return(x) }        
random.sample(N)

Thanks for your time.


Solution

  • A simple function using cumsum and ifelse would do the job without requiring costly loops. The last clause just ensures the the numbers add to tot

    f <- function(len, tot, max.size) {
      x <- sample(0:max.size, len, replace = TRUE)
      res <- ifelse(cumsum(x) > tot, 0, x)
    
      if(sum(res) < tot) {
        res[(cumsum(res) == sum(res)) & res == 0][1] <- tot - sum(res)
      }
      res
    }
    

    Testing

    f(len = 20, tot = 10, max.size = 3)
    #> [1] 3 3 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0