Loop with condition

I would like to generate a random table (type and quantity) with two conditions

generating should end after qty (quantity) is not bigger than total sum (total)

and every row should have include unique value in type.

total = 20
qty = c(2,3,4,5)
type = c(1:270)

gen.table = data.frame(type = integer(), qty = integer())
gen.table[1, ] = c(NA,1)

  
  for (j in 1:total) {
    while(sum(gen.table[1:j,][["qty"]]) <= total){  
      sb  = sample(type, 1)
      gen.table[j,][["type"]] = sb
      type = type[!type %in% sb]
      gen.table[j,][["qty"]] = sample(qty, 1)    
    }
  }

But after first iteration vectror of types is empty

>Solution :

Here is a solution. It creates the full results data.frame before the for loop and breaks the loop when the running total is greater than the wanted total.

total <- 20
qty <- c(2,3,4,5)
type <- 1:270

gen.table = data.frame(type = rep(NA_integer_, length(type)), 
                       qty = rep(NA_integer_, length(type)))

set.seed(2022)    # make results reproducible

running_total <- 0L
for (j in seq_along(type)) {
  current <- sample(qty, 1)
  running_total <- running_total + current
  if(running_total > total) break
  gen.table[j, "qty"] <- current
  new_type <- sample(type, 1)
  type <- type[type != new_type]
  gen.table[j, "type"] <- new_type
}
gen.table <- gen.table[!is.na(gen.table$qty), ]
gen.table
#>   type qty
#> 1  206   5
#> 2  196   4
#> 3  191   3
#> 4  123   3
#> 5  252   2

Created on 2022-09-06 by the reprex package (v2.0.1)

Leave a Reply