title: How to apply conditional function in data frame updating consecutive columns in R
body: <p>Consider following data frame, with x being increasing numbers (don't have to be integers) and y varying values:</p>
  
  <pre><code>x | y | d.x | d.y | abs(d.y)/d.x
  ---------------------------------
  1 | 5 |  1  |   5 | 5
  2 | 9 |  1  |   4 | 4
  3 | 1 |  1  |  -8 | 8
  4 | 7 |  1  |   6 | 6
  5 | 5 |  1  |  -2 | 2
  6 | 1 |  1  |  -4 | 4
  7 | 3 |  1  |   2 | 2
  8 | 9 |  1  |   6 | 6
  </code></pre>
  
  <p>Here, <code>d.x</code> and <code>d.y</code> represent the differenced values. I want to identify the first value of <code>abs(d.y)/d.x</code> that is above a certain threshold (e.g. >5). This would be at <code>x = 3</code>. From the next row I want to reset <code>abs(d.y)/d.x</code> so that it skips <code>x = 3</code>, i.e.:</p>
  
  <pre><code>x | y | d.x | d.y | abs(d.y)/d.x
  ---------------------------------
  1 | 5 |  1  |   5 | 5
  2 | 9 |  1  |   4 | 4
  4 | 7 |  2  |  -2 | 1
  5 | 5 |  1  |  -2 | 2
  6 | 1 |  1  |  -4 | 4
  7 | 3 |  1  |   2 | 2
  8 | 9 |  1  |   6 | 6
  </code></pre>
  
  <p>Now <code>x=8</code> would be identified as being above the treshold. This problem can easily be implemented in case there are no consecutive <code>abs(d.y)/d.x</code> that overlap at some point. The implementation can for example be done with a <code>while</code> loop, but I'm certain that someone knows how to do this with e.g. <code>ave, dplyr</code>,etc. I'm doing this with a hundreds of vector with a size of more than 10^6 entries, thus speed is of importance.</p>
  
  <p>The values above the threshold do not have to be removed, I simply want to end up with a vector that contains the index positions (i.e. 3,8, etc.).</p>
  
  <p>Thanks in advance.</p>
  
  <p>My MWE with some random numbers.</p>
  
  <pre><code># Random initialization 
  set.seed(1)
  y &lt;- randi(20,20000,1)
  x &lt;- 1:length(x)
  d.x &lt;- diff(x)
  d.y &lt;- diff(y)
  dy_dx &lt;- abs(d.y)/d.x
  idx &lt;- array(0,length(d.y)) # stores if dy_dx above threshold
  # Randomly chosen threshold
  threshold &lt;- 14
  
  while(1==1){
  # Identify values above threshold
      idx.new &lt;- match(TRUE, dy_dx &gt; threshold) # identifies first index
      if (is.na(idx.new)){
          break
      }   
  
      idx[idx.new] &lt;- 1 # flags value above threshold
      d.y[idx.new+1] &lt;- d.y[idx.new]+d.y[idx.new+1]
      d.x[idx.new+1] &lt;- d.x[idx.new]+d.x[idx.new+1]
      d.x[idx.new] &lt;- 0 # avoids that is above threshold
      dy_dx &lt;- abs(d.y)/d.x
      } 
  idx &lt;- c(0,idx)
  </code></pre>
  
  <p>UPDATE: running it as a for-loop is significantly faster:</p>
  
  <pre><code>for (i in 1:length(dy_dx)){
      if (dy_dx[i] &lt;= threshold){
        next
      }  else {
  
      idx[i] &lt;- 1
      d.y[i+1]  &lt;- d.y[i]+d.y[i+1]
      d.x[i+1] &lt;- d.x[i]+d.x[i+1]
      dy_dx[i+1] &lt;- abs(d.y[i+1])/(d.x[i+1])
      dy_dx[i] &lt;- 0
      }
    }
  </code></pre>