rloopsfor-loopconditional-statementsfind-occurrences

How to store only the first occurrence in a for loop?


I tried to code k as a cumulatively increasing variable until it reaches 15. j is supposed to store the point when k exceeds 10 for the first time. However, obviously, j is going to store all the occurrences instead which is not desirable for my purpose.

set.seed(324)
j.ind <- 1
j <- numeric()
k <- numeric()
init.k <- 0
for (i in 1:50){
  k[i] <- init.k + abs(rnorm(1,0,1))
  init.k <- k[i]
  if (k[i] >= 10){
    j[j.ind] <- i
    j.ind <- j.ind + 1
  }
  init.k <- ifelse(init.k >= 15, 0, init.k)
}

Can you suggest a way to do this which will not slow down the loop significantly as the original problem is rather huge? For this example with the given seed, j is supposed to be 17 and 36


Solution

  • You could use Reduce with option accumulate=TRUE, in combination with rle:

    set.seed(324)
    k.vectorized <- abs(rnorm(50,0,1))
    
    # cumsum with reinit for k>=15
    k.cumsum <- Reduce(f=function(x,y) {ifelse(x+y>=15,0,x+y)} ,x=k.vectorized,init=0,accumulate = T)
    
    # extract intervals above 10
    r <- rle(k.cumsum>=10)
    
    # output result
    cumsum(r$length)[which(r$values)-1]
    #> [1] 17 36