I created the following example in an attempt to clarify my question. ranPick
draws a random number for each iteration but if it draws a negative number the next two places are also assigned the same number as ranPick[i]
.
The following DOES NOT return what I intended. It counts the i
globally it seems and override the manual attempt i <- i 3
.
I know that I can use while loop
or different index other than i
. But I am wondering if it is possible to tell this for loop to jump over some iterations conditionally?
ranPick <- numeric()
for (i in 1:100){
ranPick[i] <- (round(rnorm(1, 1, 5)))
if (ranPick[i] < 0){
ranPick[i:(i 2)] <- ranPick[i]
i <- i 3
}
}
CodePudding user response:
In general, next
tells a for-loop to skip TO the next iteration. I dont think there is a way to tell a for loop to skip THE next iteration(s) hence this workaround might be the way to go.
You define a counter variable that is filled with the number of iterations to skip if a specific case happens, e.g. sample value < 0. At the beginning of each iteration this counter vriable is checked whether the iteration should be skipped. If so, 1
is substracted from the counter and the iteration is skipped by using the keyword next
.
set.seed(123)
# assign vetor of desired length
len <- 10
ranPick <- numeric(len)
# use counter
skip_count <- 0
for (i in seq_len(len)){
# skip if already filled and counter is != 0
if (skip_count != 0) {
# reduce counter by 1 to indicate an iteration was skipped
skip_count <- skip_count - 1
print("skip")
next
}
ranPick[i] <- (round(rnorm(1, 1, 5)))
if (ranPick[i] < 0){
print("<0")
# min ensures the vector length does not exceed the desired length
ranPick[i:min(i 2, len)] <- ranPick[i]
# set counter to desired iterations to skip
skip_count <- 2
}
}
#> [1] "<0"
#> [1] "skip"
#> [1] "skip"
#> [1] "<0"
ranPick
#> [1] -2 -2 -2 0 9 1 2 10 3 -5
Note that I added a min()
call to ensure the outcome vector is not longer than the desired number of iterations. In this example, iteration 10 produces a negative number and hence -5
would be added 3 times, resulting in a vector of length 12.
CodePudding user response:
As mentioned by Robert Hacken and mnist, you can't control the behavior of the index variable at the beginning of each loop.
A few options for the example problem:
lranPick <- vector("list", 3)
set.seed(1167952300)
ranPick <- numeric(100)
skip <- 0L
for (i in 1:100){
if (skip) {
skip <- skip - 1L
} else {
ranPick[i] <- round(rnorm(1, 1, 5))
if (ranPick[i] < 0){
ranPick[i:(i 2)] <- ranPick[i]
skip <- 2L
}
}
}
lranPick[[1]] <- ranPick[1:100]
set.seed(1167952300)
ranPick <- numeric(100)
skip <- 0L
for (i in 1:100){
if (skip) {
skip <- skip - 1L
ranPick[i] <- ranPick[i - 1L]
} else {
ranPick[i] <- round(rnorm(1, 1, 5))
skip <- 2L*(ranPick[i] < 0)
}
}
lranPick[[2]] <- ranPick
set.seed(1167952300)
ranPick <- round(rnorm(100, 1, 5))
lranPick[[3]] <- rep.int(ranPick, 1L 2L*(ranPick < 0))[1:100]
identical(lranPick[-1], lranPick[-3])
#> [1] TRUE