Embedding a time series with time delay in R — Part II

Some months ago, I posted a function that extended the base R function embed() to allow for time delay embedding. Today, David Gonzales alerted me to an inconsistency between embed() and Embed().

The example David used was

<span class="go">R> (x <- seq(1,20,3))</span>
<span class="go">[1]  1  4  7 10 13 16 19</span>
<span class="go">R> embed(x, 4)</span>
<span class="go">     [,1] [,2] [,3] [,4]</span>
<span class="go">[1,]   10    7    4    1</span>
<span class="go">[2,]   13   10    7    4</span>
<span class="go">[3,]   16   13   10    7</span>
<span class="go">[4,]   19   16   13   10</span>
<span class="go">R> Embed(x, 4)</span>
<span class="go">     [,1] [,2] [,3] [,4]</span>
<span class="go">[1,]    4    3    2    1</span>
<span class="go">[2,]    7    6    5    4</span>
<span class="go">[3,]   10    9    8    7</span>
<span class="go">[4,]   13   12   11   10</span>

where Embed() clearly returns an incorrect result.

In this post, I present an explanation of the problem and address the shortcomings in the original code with an updated version of Embed().

The reason the original version of Embed() doesn’t work with David’s example is that when I wrote it, I had in mind that it would work on the indices of the time series, not the values of the time series. I had overlooked that embed() returned the embedded time series, not the indices — the problem of testing with vectors like 1:10!

Updating Embed() to output the same result as embed() is a trivial matter; we just get the function to work with seq_along(x) and not x itself and then use the old Embed() behaviour to index x to return the embedded time series. As an added extra, as we are generating the indices anyway, we can optionally have the function return those instead of the embedded series.

Here is the updated version of Embed()

Embed <span class="o"><-</span> <span class="kr">function</span><span class="p">(</span>x<span class="p">,</span> m<span class="p">,</span> d <span class="o">=</span> <span class="m">1</span><span class="p">,</span> indices <span class="o">=</span> <span class="kc">FALSE</span><span class="p">,</span> as.embed <span class="o">=</span> <span class="kc">TRUE</span><span class="p">)</span> <span class="p">{</span>
    n <span class="o"><-</span> length<span class="p">(</span>x<span class="p">)</span> <span class="o">-</span> <span class="p">(</span>m<span class="m">-1</span><span class="p">)</span><span class="o">*</span>d
    X <span class="o"><-</span> seq_along<span class="p">(</span>x<span class="p">)</span>
    <span class="kr">if</span><span class="p">(</span>n <span class="o"><=</span> <span class="m">0</span><span class="p">)</span>
        stop<span class="p">(</span><span class="s">"Insufficient observations for the requested embedding"</span><span class="p">)</span>
    out <span class="o"><-</span> matrix<span class="p">(</span>rep<span class="p">(</span>X<span class="p">[</span>seq_len<span class="p">(</span>n<span class="p">)],</span> m<span class="p">),</span> ncol <span class="o">=</span> m<span class="p">)</span>
    out<span class="p">[,</span><span class="m">-1</span><span class="p">]</span> <span class="o"><-</span> out<span class="p">[,</span><span class="m">-1</span><span class="p">,</span> drop <span class="o">=</span> <span class="kc">FALSE</span><span class="p">]</span> <span class="o">+</span>
        rep<span class="p">(</span>seq_len<span class="p">(</span>m <span class="o">-</span> <span class="m">1</span><span class="p">)</span> <span class="o">*</span> d<span class="p">,</span> each <span class="o">=</span> nrow<span class="p">(</span>out<span class="p">))</span>
    <span class="kr">if</span><span class="p">(</span>as.embed<span class="p">)</span>
        out <span class="o"><-</span> out<span class="p">[,</span> rev<span class="p">(</span>seq_len<span class="p">(</span>ncol<span class="p">(</span>out<span class="p">)))]</span>
    <span class="kr">if</span><span class="p">(</span><span class="o">!</span>indices<span class="p">)</span>
        out <span class="o"><-</span> matrix<span class="p">(</span>x<span class="p">[</span>out<span class="p">],</span> ncol <span class="o">=</span> m<span class="p">)</span>
    out
<span class="p">}</span>

The main difference is that we create X <- seq_along(x) and create out using that rather than the time series (x). I’ve also added a new argument, indices, that defaults to FALSE. If we want Embed() to return the indices of the embedded time series, call the function with indices = FALSE.

The new version of Embed() gives the same results as before and is consistent with embed() when we pass it a time series that is identical to its indices

<span class="go">R> embed(1:5, 2)</span>
<span class="go">     [,1] [,2]</span>
<span class="go">[1,]    2    1</span>
<span class="go">[2,]    3    2</span>
<span class="go">[3,]    4    3</span>
<span class="go">[4,]    5    4</span>
<span class="go">R> Embed(1:5, 2)</span>
<span class="go">     [,1] [,2]</span>
<span class="go">[1,]    2    1</span>
<span class="go">[2,]    3    2</span>
<span class="go">[3,]    4    3</span>
<span class="go">[4,]    5    4</span>

but it also works for time series like those in David’s example:

<span class="go">R> (x <- seq(1,20,3))</span>
<span class="go">[1]  1  4  7 10 13 16 19</span>
<span class="go">R> embed(x, 4)</span>
<span class="go">     [,1] [,2] [,3] [,4]</span>
<span class="go">[1,]   10    7    4    1</span>
<span class="go">[2,]   13   10    7    4</span>
<span class="go">[3,]   16   13   10    7</span>
<span class="go">[4,]   19   16   13   10</span>
<span class="go">R> Embed(x, 4)</span>
<span class="go">     [,1] [,2] [,3] [,4]</span>
<span class="go">[1,]   10    7    4    1</span>
<span class="go">[2,]   13   10    7    4</span>
<span class="go">[3,]   16   13   10    7</span>
<span class="go">[4,]   19   16   13   10</span>

and we have the added benefit of being able to return the indices of the embedded time series

<span class="go">R> Embed(x, 4, indices = TRUE)</span>
<span class="go">     [,1] [,2] [,3] [,4]</span>
<span class="go">[1,]    4    3    2    1</span>
<span class="go">[2,]    5    4    3    2</span>
<span class="go">[3,]    6    5    4    3</span>
<span class="go">[4,]    7    6    5    4</span>

Now I just need to do something on the recurrence plot that I originally wrote Embed() for!

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)