Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Random sequence from fixed ensemble that contains at least one of each character

Tags:

random

r

sample

I am trying to generate a random sequence from a fixed number of characters that contains at least one of each character.

For example having the ensemble

m = letters[1:3]

I would like to create a sequence of N = 10 elements that contain at least one of each m characters, like

a
a
a
a
b
c
c
c
c
a

I tried with sample(n,N,replace=T) but in this way also a sequence like

a
a
a
a
a
c
c
c
c
a

can be generated that does not contain b.

like image 248
user3036416 Avatar asked Oct 13 '14 22:10

user3036416


2 Answers

f <- function(x, n){
    sample(c(x, sample(m, n-length(x), replace=TRUE)))
}
f(letters[1:3], 5)
# [1] "a" "c" "a" "b" "a"
f(letters[1:3], 5)
# [1] "a" "a" "b" "b" "c"
f(letters[1:3], 5)
# [1] "a" "a" "b" "c" "a"
f(letters[1:3], 5)
# [1] "b" "c" "b" "c" "a"
like image 63
Josh O'Brien Avatar answered Oct 13 '22 12:10

Josh O'Brien


Josh O'Briens answer is a good way to do it but doesn't provide much input checking. Since I already wrote it might as well present my answer. It's pretty much the same thing but takes care of checking things like only considering unique items and making sure there are enough unique items to guarantee you get at least one of each.

at_least_one_samp <- function(n, input){
  # Only consider unique items.
  items <- unique(input)

  unique_items_count <- length(items)
  if(unique_items_count > n){
    stop("Not enough unique items in input to give at least one of each")
  }

  # Get values for vector - force each item in at least once
  # then randomly select values to get the remaining.
  vals <- c(items, sample(items, n - unique_items_count, replace = TRUE))
  # Now shuffle them
  sample(vals)
}

m <- c("a", "b", "c")
at_least_one_samp(10, m)
like image 40
Dason Avatar answered Oct 13 '22 14:10

Dason