Manos
Manos

Reputation: 103

break a for loop when a specific condition is satisfied and continue to next iteration R version 3.0.2 windows

Hello everyone I am new to R and I am trying to create a loop using the following code :

   x<- rep(NA, 10)
  for(i in 1:10)  {
  +  x[i]<- 1+i 
  if(i==5) # when a specific condition is satisfied #
  x[i]<- 2 # i want the loop to continue this way #
  }

so the result will be something like : 2 3 4 5 6 2 2 2 2 2 What I think is that i have to use break or next statement but i cannot understand their use. Any suggestions . In addition I am looking for any relevant material to study ...Thanks in advance. My code goes like this

set.seed(10)
x<- rep(NA, 20)
tmp<- rep(FALSE, 20)
for(i in 1:20) {
x[i]<- runif(1)
tmp<- x[i]<0.5
if(2 * sum(tmp) - i + 1 > 2) {
tmp[i]<- x[i]<0.2
} else {
tmp[i]<- x[i]<0.8
}
}

But i cannot make it work . In fact i want the possibility to switch to 0.2 when 2 * sum(tmp) - i + 1 > 2 condition is satisfied and switch to 0.8 when 2 * sum(tmp) - i + 1 < -2 condition is satisfied or vice versa.

My goal is to create a vector as following. Take a random x from random uniform(0,1) if x<0.5 then the vector takes value a else takes b . This continues until the number of a's-the number of b's > 2 at this point i want to change the possibility that a's and b's are assigned to the vector to 0.2 (if x<0.2 then a). This probability i want to change again if the number of b's - the number of a's > 2 to 0.8(if x<0.8 then a). However because i have random numbers i may have the above situation vice versa. (first b's-a's>2 then a's-b's>2) .finally sth like vector<- a,b,a,a,a,b,b,a –
Hello again. Using your help i finally managed to get close to my goal but i still have a problem. Here is the code :

n1<- 0
n2<- 0
n<- 20
f<- rep(NA,20)
set.seed(10) 
d<- function(n){
x<- runif(20,0,1)
for(i in 1:20) {
if((n1-n2)<=2) {
f[i]<- ifelse(x[i]<0.5, 'a', 'b')
} else if((n1-n2)>2) { 
f[i]<- ifelse(x[i]<0.2, 'a', 'b')
} else if((n2-n1)>2) {
f[i]<- ifelse(x[i]<0.8, 'a', 'b')
} 
if(f[i]=='a')  {
n1<- n1 + 1 
} else  { 
n2<- n2 + 1
print(data.frame(f,x))
print(n1)
print(n2)
}
}
}
d(20)

and the rusults are

   f          x
1  b 0.50747820
2  a 0.30676851
3  a 0.42690767
4  b 0.69310208
5  a 0.08513597
6  a 0.22543662
7  a 0.27453052
8  b 0.27230507
9  b 0.61582931
10 a 0.42967153
11 b 0.65165567
12 b 0.56773775
13 a 0.11350898
14 b 0.59592531
15 a 0.35804998
16 a 0.42880942
17 a 0.05190332
18 b 0.26417767
19 a 0.39879073
20 b 0.83613414

In line seven as you can see a's-b-s=5-2=3 and thus in line 8 the sampling probability for a has been changed to 0.2. And here is my problem. I want from now to keep sampling with this probability until or when b's-a's>2 and the probability should be changed to 0.8. This means that in line ten where the runif number is >0.2 i should have b and not a. Can you help me? Thanks in advance

Upvotes: 0

Views: 562

Answers (2)

Roland
Roland

Reputation: 132626

You really need to work on explaining yourself more clearly. I hope I interpreted your last comment correctly.

You don't need runif here, you can simply pass probabilities to sample:

#random seed for reproducibility
set.seed(42)
#possible values
vals <- c("a", "b")
#number of result values
n <- 1e5
#pre-allocate result vector
res <- character(n)
#numbers of first and second value
n1 <- 0
n2 <- 0
#probability
p <- 0.5
#loop
for (i in seq_len(n)) {
  #if difference between number of value1 and value2
  #is greater than 2
  #change the probability for sampling the value that is present in lower numbers
  #to 0.2 and the other to 0.8
  if (abs(n1-n2) > 2) {
    p <- (n1>n2)*0.2 + (n1<n2)*0.8
  }
  #sample a value with the given probabilities
  res[i] <- sample(vals, 1, prob=c(p, 1-p))  
  #increase counter
  if (res[i]==vals[1]) n1 <- n1 + 1 else n2 <- n2 + 1
}
head(res, 20)
#[1] "a" "a" "b" "a" "a" "b" "b" "b" "b" "b" "b" "a" "b" "a" "a" "b" "b" "a" "a" "a"
table(res)
# res
#     a     b 
# 49999 50001 

Edit:

Let me demonstrate that you can replicate the result of sample with runif:

set.seed(42)
x <- sample(c("a", "b"), 20, TRUE)
set.seed(42)
y <- ifelse(runif(20)<0.5, "a", "b")

identical(x, y)
#[1] TRUE

Upvotes: 0

Jilber Urbina
Jilber Urbina

Reputation: 61154

Try this

x<- rep(NA, 10)
for(i in 1:10)  {
  if(i<5){
    x[i]<- 1+i 
  } else{
    x[i]<- 2
  }
}

> x
 [1] 2 3 4 5 2 2 2 2 2 2

Nevertheless, you don't need a for loop to get your desired output, try ifelse instead:

> x <- 1:10
> ifelse(x<5, x+1, 2)
 [1] 2 3 4 5 2 2 2 2 2 2

Upvotes: 1

Related Questions