Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why lag in r is not working for matrix?

Tags:

r

lag

I am trying to lag a matrix:

> B = matrix( c(2, 4, 3, 1, 5, 7),  nrow=3, ncol=2)
> B
     [,1] [,2]
[1,]    2    1
[2,]    4    5
[3,]    3    7
> lag(B)
     [,1] [,2]
[1,]    2    1
[2,]    4    5
[3,]    3    7

Why does lag(B) NOT give:

> lag(B)
     [,1] [,2]
[1,]    0    0
[2,]    2    1
[3,]    4    5
like image 576
ManInMoon Avatar asked May 20 '13 13:05

ManInMoon


People also ask

What is LAG () in R?

lag lag shifts the times one back. It does not change the values, only the times. Thus lag changes the tsp attribute from c(1, 4, 1) to c(0, 3, 1) . The start time is shifted from 1 to 0, the end time is shifted from 4 to 3 and since shifts do not change the frequency the frequency remains 1.

What is the opposite of lag in R?

The opposite of lag() function is lead()

How do you create a lag variable in Matlab?

When you shift the data in each variable forward, lag fills the first row of TT2 with missing data indicators. TT2 = lag( TT1 , n ) shifts data by n time steps. n must be an integer. If n is positive, then lag shifts the data forward in time (a lag).


2 Answers

It is because lag shifts the times of the object, not the data values. Its really intended for time series objects.

When lag is used on a plain matrix, B, the lag.default method is invoked. Since there is no time associated with a plain matrix it assumes the times are 1, 2, ..., NROW(B) :

> time(B)
[1] 1 2 3
attr(,"tsp")
[1] 1 3 1

and shifts the times by one so that they now start from 0:

> time(lag(B))
[1] 0 1 2
attr(,"tsp")
[1] 0 2 1

Use a time series class if you want to combine objects that have times. (The first column is the times in the displays below.)

> library(zoo)
>
> # zooreg - regular series or almost so
> B.zr <- zooreg(B)
> merge(B.zr, lag(B.zr))
  B.zr.1 B.zr.2 lag(B.zr).1 lag(B.zr).2
0     NA     NA           2           1
1      2      1           4           5
2      4      5           3           7
3      3      7          NA          NA

> # zoo - irregular series
> B.z <- zoo(B)
> merge(B.z, lag(B.z))
  B.z.1 B.z.2 lag(B.z).1 lag(B.z).2
1     2     1          4          5
2     4     5          3          7
3     3     7         NA         NA

Note the difference between lag.zooreg which can extend beyond the range of the original times producing a 0 time and lag.zoo which cannot because there is no regularity assumption in the latter.

We can also use ts class which assumes regularity so a 0 time can be produced but there is no merge.ts making it less useful here.

like image 198
G. Grothendieck Avatar answered Sep 18 '22 12:09

G. Grothendieck


I've never understood lag function, instead I'd use Lag from quantmod package:

> # library(quantmod)
> apply(B, 2, Lag)
     [,1] [,2]
[1,]   NA   NA
[2,]    2    1
[3,]    4    5

If you want (or need) lag a matrix without ts attributes one way could be using apply and Lag from quantmod package, but if you don't want to install a package for just one function, then you could write your own function, an idea would be like this:

lag.matrix <- function(x, k=1){
  N <- ncol(B)
  l <- matrix(embed(x,k+1)[, -c(1:(k*N))], ncol=N)
  NAs <- matrix(rep(NA, k*N), ncol=N)
  rbind(NAs, l)
}
> lag.matrix(B, k=1)
     [,1] [,2]
[1,]   NA   NA
[2,]    2    1
[3,]    4    5
> lag.matrix(B, k=2)
     [,1] [,2]
[1,]   NA   NA
[2,]   NA   NA
[3,]    2    1

Another soluction could be the one posted as a comment by @GSee which uses lag as you wish.

> lag(xts(B, .POSIXct(0)+0:(nrow(B)-1)))
                    [,1] [,2]
1970-01-01 01:00:00   NA   NA
1970-01-01 01:00:01    2    1
1970-01-01 01:00:02    4    5
like image 41
Jilber Urbina Avatar answered Sep 19 '22 12:09

Jilber Urbina