Chen
Chen

Reputation: 111

Repeat a loop until it satisfies a specific condition

Anybody can help me on this? Suppose the "p" is totally exogenous and following a uniform distribution. Then I want to generate "z", which is a TRUE(=1) or FALSE(=0) dummy, and has the property that the summation of each three elements (1-3, 4-6, 7-9,..., 58-60) in "z" should be greater than 0.

For example, if I get a "z" like {1 0 0 1 1 0 0 0 0 0 1 0...}, I hope to repeat the loop again ( since sum(z[7:9])=0 ) to draw a different "error" until I get a new "z" like {1 1 0 0 0 1 0 1 0 1 0 0...} where all summations for each three elements are greater than 0. The code I use is as follows. Where am I wrong?

   set.seed(005)
   p<-runif(60, 0, 1)

   for (i in 1:20) {

     repeat {
       error= -0.2*log((1/runif(60, 0, 1))-1) # a random component
       z=(p<0.5+error) # TRUE/FALSE condition
       z=replace(z, z==TRUE, 1) # replace z to 1 if z is true, else z=0

       if (sum(z[(3*i-2):(3*i)])>0) {break}
      }

   }

Upvotes: 0

Views: 8230

Answers (1)

TheComeOnMan
TheComeOnMan

Reputation: 12875

Your for loop generates a new z for every i. I don't think that's what you're trying to do. From what I can understand, you're trying to generate a new z and then use a for loop with the counter i to check for sums of three consecutive elements. If so, then you need to have one loop to generate new zs, and then another one inside this loop which checks for the sum of three consecutive elements.

I think this does what you want. But when I run it it seems unlikely that you will get a satisfactory z soon.

   set.seed(005)
   p<-runif(60, 0, 1)

   invalidentriesexist =1

      while(invalidentriesexist == 1) {
         error = -0.2*log((1/runif(60, 0, 1))-1) # a random component
         z=(p<0.5+error) # TRUE/FALSE condition

         z=replace(z, z==TRUE, 1) # replace z to 1 if z is true, else z=0
         z=replace(z, z==FALSE, 0) # replace z to 1 if z is true, else z=0

         invalidentriesexist = 0
         i = 1
         while ( i <=20 & invalidentriesexist == 0 ) {
            invalidentriesexist = 0
            if (sum(z[((3*i)-2):(3*i)])==0) {invalidentriesexist = 1}
            cat(i,'\n')
            cat(invalidentriesexist,'\n')
            cat(paste(z,collapse = ","),'\n')
            cat(z[((3*i)-2):(3*i)],'\n\n')
            i = i + 1
         } 

      } 

Upvotes: 4

Related Questions