The Lag function in quantmod can accept a vector for its "k" periods to lag (and output a matrix or array), but I can find no corresponding way to accomplish such through a forward-looking function - like Next() or lead().
For example,
variable <- runif(5,1,30)
my.k <- c(2, 3)
Lag(variable, my.k)
returns:
Lag.2 Lag.3
[1,] NA NA
[2,] NA NA
[3,] 18.71971 NA
[4,] 10.98429 18.71971
[5,] 17.19299 10.98429
However, the reciprocal to quantmod's Lag command, i.e., the Next() command, returns the following:
> variable <- runif(5,1,30)
> my.k <- c(2, 3)
> Next(variable, my.k)
Error in Next.numeric(variable, my.k) : k must be a non-negative integer
I've tried including as.integer(my.k), but get the same error. I've also reviewed the help notes through both ?Lag and ?Next.
I began by trying the lag() and lead() functions from the dplyr package - but they both require a "Positive integer of length 1" for "the number of positions to lead or lag by", and provide the following error when trying to include my.k in their respective arguments for n:
Error: `n` must be a nonnegative integer scalar, not a double vector of length 2.
QUESTION: How can I use my.k (my created vector) in some forward looking function - like Next() or lead() - the same way that i am able to use it in the quantmod Lag function? Is there an easy way to do this?
lag.zoo
in the zoo package and flag
in the collapse package both support forward and backward vectorized lags. Either can create all the my.k
lags in one line of code without iterating.
The first example below converts variable
to zoo class and then performs the lag using lag.zoo
. zoo objects typically do not need padding but if this is intended for use within a data frame which can't handle that we add na.pad = TRUE
. Then optionally convert back to plain numeric using coredata
. Note that dplyr clobbers the generic lag
function in R so either do not load dplyr, load it using library(dplyr, exclude = c("lag", "filter"))
or use stats::lag
to force use of the lag
generic in base R which in turn will dispatch lag.zoo
. If my.k
has names, they don't in the question, those names will be used to name the output columns.
The second example below uses flag
in the collapse package.
Note that base R's lag
is defined such that a series resulting from a positive lag starts earlier. lag.zoo
is consistent with that convention. On the other hand in collapse a positive lag means the series starts later. Thus to refer to past values the series starts later so use negative lags with lag.zoo
and positive lags with flag
. To pull values backward from the future use the negative of those lags in both cases.
The code in the question is not reproducible since it uses random numbers without setting the seed so we set the seed as shown in the Note at the end to produce the example input.
library(zoo)
coredata(stats::lag(as.zoo(variable), -my.k, na.pad = TRUE))
## lag-2 lag-3
## [1,] NA NA
## [2,] NA NA
## [3,] 9.339748 NA
## [4,] 23.860849 9.339748
## [5,] 12.860331 23.860849
coredata(stats::lag(as.zoo(variable), my.k, na.pad = TRUE))
## lag2 lag3
## [1,] 12.86033 26.60750
## [2,] 26.60750 28.27355
## [3,] 28.27355 NA
## [4,] NA NA
## [5,] NA NA
library(collapse)
flag(variable, my.k)
## L2 L3
## [1,] NA NA
## [2,] NA NA
## [3,] 9.339748 NA
## [4,] 23.860849 9.339748
## [5,] 12.860331 23.860849
## attr(,"class")
## [1] "matrix"
flag(variable, -my.k)
## F2 F3
## [1,] 12.86033 26.60750
## [2,] 26.60750 28.27355
## [3,] 28.27355 NA
## [4,] NA NA
## [5,] NA NA
## attr(,"class")
## [1] "matrix"
The input in reproducible form (using set.seed
):
set.seed(123)
variable <- runif(5,1,30); variable
## [1] 9.339748 23.860849 12.860331 26.607505 28.273551
my.k <- c(2, 3)