Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pick a random number, always with increasing value over last random number picked

Tags:

random

r

sample

How would I efficiently go about taking a 1-by-1 ascending random sample of the values 1:n, making sure that each of the randomly sampled values is always higher than the previous value?

e.g.:

For the values 1:100, get a random number, say which is 61. (current list=61)
Then pick another number between 62 and 100, say which is 90 (current list=61,90)
Then pick another number between 91 and 100, say which is 100.
Stop the process as the max value has been hit (final list=61,90,100)

I have been stuck in loop land, thinking in this clunky manner:

a1 <- sample(1:100,1)

if(a1 < 100) {
    a2 <- sample((a+1):100,1)
        }

etc etc...

I want to report a final vector being the concatenation of a1,a2,a(n):

result <- c(a1,a2)

Even though this sounds like a homework question, it is not. I thankfully left the days of homework many years ago.

like image 985
thelatemail Avatar asked Sep 26 '12 04:09

thelatemail


3 Answers

Coming late to the party, but I think this is gonna rock your world:

unique(cummax(sample.int(100)))
like image 82
flodel Avatar answered Nov 07 '22 05:11

flodel


This uses a while loop and is wrapped in a function

# from ?sample
resample <- function(x, ...) x[sample.int(length(x), ...)]

sample_z <-  function(n){
  z <- numeric(n)
  new <- 0
  count <- 1

  while(new < n){
    from <- seq(new+1,n,by=1)
    new <- resample(from, size= 1)
    z[count] <- new
    if(new < n)  count <- count+1
  }

  z[1:count]
}

set.seed(1234)

sample_z(100)
## [1]  12  67  88  96 100

Edit

note the change to deal with when the new sample is 100 and the way sample deals with an integer as opposed to a vector for x

Edit 2

Actually reading the help for sample gave the useful resample function. Which avoids the pitfalls when length(x) == 1

like image 23
mnel Avatar answered Nov 07 '22 07:11

mnel


Not particularly efficient but:

X <- 0
samps <- c()
while (X < 100) {
    if(is.null(samps)) {z <- 1 } else {z <- 1 + samps[length(samps)]}
    if (z == 100) {
        samps <- c(samps, z)
    } else { 
        samps <- c(samps, sample(z:100, 1))
    }
    X <- samps[length(samps)]
}

samps EDIT: Trimming a little fat from it:

samps <- c()
while (is.null(samps[length(samps)]) ||  samps[length(samps)] < 100 ) {
    if(is.null(samps)) {z <- 1 } else {z <- 1 + samps[length(samps)]}
    if (z == 100) {
        samps <- c(samps, z)
    } else { 
        samps <- c(samps, sample(z:100, 1))
    }
}

samps
like image 3
Tyler Rinker Avatar answered Nov 07 '22 05:11

Tyler Rinker