Reputation: 7005
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
Upvotes: 7
Views: 4362
Reputation: 3314
The EASIEST way to lag a matrix in R is by using the `embed()' function. Here is a quick reproducible example:
> # Create a 5x2 matrix
> m <- replicate(2, 1:5)
> m
[,1] [,2]
[1,] 1 1
[2,] 2 2
[3,] 3 3
[4,] 4 4
[5,] 5 5
>
> # Use the 'embed()' function to lag the matrix
> lag_m <- embed(m, 3)
> lag_m
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 3 2 2 1 1
[2,] 4 4 3 3 2 2
[3,] 5 5 4 4 3 3
A few important words about the embed() function and its output.
The first argument of the function is the matrix we want to lag. The second argument; however, is the number of lags we want "plus 1". Therefore, embed(matrix, 3) means that we want to lag the matrix by 2 time periods.
. the first two columns represent the original m matrix, but the number of rows is adjusted for the number of lags (5 rows originally minus a 2-time-period lag)
. the second set of columns (columns 3 and 4) are the m matrix lagged by 1 time period
. the third set of columns (columns 5 and 6) are the m matrix lagged by 2 time periods.
Upvotes: 1
Reputation: 269481
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.
Upvotes: 4
Reputation: 61154
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
Upvotes: 2
Reputation: 42639
l <- matrix(0,nrow(B),nrow(B))
l[-1,-nrow(B)] <- diag(nrow(B)-1)
l
## [,1] [,2] [,3]
## [1,] 0 0 0
## [2,] 1 0 0
## [3,] 0 1 0
l %*% B
## [,1] [,2]
## [1,] 0 0
## [2,] 2 1
## [3,] 4 5
Upvotes: 1