Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>For the first function you're looking for the cumulative number of periods during which series <code>x</code> is lower/higher than <code>y</code>. For that you can use this handy function <code>CumCount()</code> built from <code>cummax</code>. First some sample data:</p> <pre><code>set.seed(1) x &lt;- sample(1:5,20,T) y &lt;- sample(1:5,20,T) CumCount &lt;- function(x) { z &lt;- cumsum(x) z - cummax(z*(!x)) } CumLow = CumCount(x&lt;y) CumHigh = CumCount(x&gt;y) </code></pre> <p>For your second computation, you're trying to find the <em>cumulative minimum</em> <code>x</code> value <em>within each period</em> during which <code>x &lt; y</code>. For this the <code>rle</code> function is very useful ("run-length-encoding").</p> <pre><code># runs equals the length of each phase (x &lt; y or x &gt; y) runs &lt;- rle(CumLow &gt; 0)$lengths # starts is the number of periods prior to each phase... starts &lt;- c(0,cumsum(runs)[-length(runs)]) #... which we use to build "blocks", a list of indices of each phase. blocks &lt;- mapply( function(x,y) x+y, starts, lapply(runs,seq)) # now apply the cummin function within each block: # (remember to mask it by CumLow &gt; 0 -- # we only want to do this within the x&lt;y phase) BlockCumMin &lt;- unlist(sapply(blocks, function(blk) cummin(x[blk]))) * (CumLow &gt; 0) </code></pre> <p>Now we put it all together:</p> <pre><code> &gt; cbind(x,y, CumLow, CumHigh, BlockCumMin) x y CumLow CumHigh BlockCumMin [1,] 3 4 1 0 3 [2,] 4 2 0 1 0 [3,] 2 2 0 0 0 [4,] 2 5 1 0 2 [5,] 4 4 0 0 0 [6,] 2 2 0 0 0 [7,] 4 1 0 1 0 [8,] 1 3 1 0 1 [9,] 2 5 2 0 1 [10,] 1 3 3 0 1 [11,] 2 5 4 0 1 [12,] 1 4 5 0 1 [13,] 4 2 0 1 0 [14,] 5 3 0 2 0 [15,] 4 1 0 3 0 [16,] 4 1 0 4 0 [17,] 3 4 1 0 3 [18,] 3 1 0 1 0 [19,] 5 3 0 2 0 [20,] 4 4 0 0 0 </code></pre> <p>Note that this problem is related to <a href="https://stackoverflow.com/questions/5012516/count-how-many-consecutive-values-are-true/5016069#5016069">this question</a></p> <p><strong><em>Update.</em></strong> For the more general case where you have a <code>series</code> vector, a <code>lengths</code> vector (of same length as <code>series</code>), and you want to produce a result called <code>BlockMins</code> where <code>BlockMins[i]</code> is the minimum of the <code>lengths[i]</code> block of <code>series</code> ending at position <code>i</code>, you could do the following. Since the lengths are arbitrary, this is no longer a cumulative min; for each <code>i</code> you have to take the min of the <code>length[i]</code> elements of <code>series</code> ending at position <code>i</code>:</p> <pre><code>set.seed(1) series &lt;- sample(1:5,20,T) lengths &lt;- sample(3:5,20,T) BlockMins &lt;- sapply(seq_along(lengths), function(i) min( series[ i : max(1, (i - lengths[i]+1)) ]) ) &gt; cbind(series, lengths, BlockMins) series lengths BlockMins [1,] 1 5 1 [2,] 1 4 1 [3,] 3 3 1 [4,] 4 4 1 [5,] 5 3 3 [6,] 1 4 1 [7,] 1 5 1 [8,] 4 3 1 [9,] 2 5 1 [10,] 2 4 1 [11,] 1 5 1 [12,] 2 5 1 [13,] 2 3 1 [14,] 2 4 1 [15,] 4 5 1 [16,] 3 5 2 [17,] 5 3 3 [18,] 1 4 1 [19,] 5 3 1 [20,] 3 3 1 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload