Quantmod / R 中的滞后函数与下一个函数

Lag Function vs Next Function in Quantmod / R

quantmod 中的 Lag 函数可以接受其“k”周期滞后的向量(并输出矩阵或数组),但我找不到相应的方法来通过前瞻性函数实现这一点 - 比如 Next () 或 lead().

例如,

    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

然而,quantmod 的 Lag 命令的倒数,即 Next() 命令,returns 如下:

   > 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

我试过包含 as.integer(my.k),但出现同样的错误。我还通过 ?Lag 和 ?Next 查看了帮助说明。

我开始尝试 dplyr 包中的 lag() 和 lead() 函数——但它们都需要一个“长度为 1 的正整数”来表示“领先或落后的位置数”,并提供尝试在 n:

的各自参数中包含 my.k 时出现以下错误
Error: `n` must be a nonnegative integer scalar, not a double vector of length 2.

问题:我如何在一些前瞻性函数中使用 my.k(我创建的向量)——比如 Next() 或 lead()——与我在 quantmod Lag 中使用它的方式相同功能?有没有简单的方法可以做到这一点?

似乎 next() 没有矢量化。这是一个 tidyverse 方法:

library(tidyverse)

set.seed(123)

variable <- tibble(values = runif(5,1,30))
my.k <- c(2, 3)

variable
#> # A tibble: 5 x 1
#>   values
#>    <dbl>
#> 1   9.34
#> 2  23.9 
#> 3  12.9 
#> 4  26.6 
#> 5  28.3

#tidyverse easy way
mutate(variable, lead_1 = lead(values, 2),
       lead_2 = lead(values, 3))
#> # A tibble: 5 x 3
#>   values lead_1 lead_2
#>    <dbl>  <dbl>  <dbl>
#> 1   9.34   12.9   26.6
#> 2  23.9    26.6   28.3
#> 3  12.9    28.3   NA  
#> 4  26.6    NA     NA  
#> 5  28.3    NA     NA

#tidyverse when my.k is big
my.k %>% map(~ transmute(variable, lead = dplyr::lead(values, .x))) %>%
    map2_dfc(my.k, ~set_names(.x, paste0('lead_', as.character(.y))))
#> # A tibble: 5 x 2
#>   lead_2 lead_3
#>    <dbl>  <dbl>
#> 1   12.9   26.6
#> 2   26.6   28.3
#> 3   28.3   NA  
#> 4   NA     NA  
#> 5   NA     NA

reprex package (v2.0.0)

创建于 2021-06-12
zoo 包中的

lag.zoo 和 collapse 包中的 flag 都支持前向和后向向量化滞后。两者都可以在一行代码中创建所有 my.k 滞后而无需迭代。

下面的第一个示例将 variable 转换为动物园 class,然后使用 lag.zoo 执行延迟。动物园对象通常不需要填充,但如果这是为了在无法处理的数据框中使用,我们添加 na.pad = TRUE。然后可以选择使用 coredata 转换回纯数字。请注意,dplyr 破坏了 R 中的泛型 lag 函数,因此要么不加载 dplyr,使用 library(dplyr, exclude = c("lag", "filter")) 加载它,要么使用 stats::lag 强制使用基础 R 中的 lag 泛型这反过来将调度 lag.zoo。如果 my.k 有名称,但它们不在问题中,这些名称将用于命名输出列。

下面的第二个例子在折叠包中使用了flag

请注意,基数 R 的 lag 定义为由正滞后产生的序列更早开始。 lag.zoo 与该约定一致。另一方面,在 collapse 中,正滞后意味着系列开始得晚。因此,为了参考过去的值,序列开始较晚,因此使用 lag.zoo 的负滞后和 flag 的正滞后。 要从未来拉回价值,请在两种情况下使用这些滞后的负数。

问题中的代码不可重现,因为它使用随机数而不设置种子,因此我们按照最后注释中所示设置种子以生成示例输入。

lag.zoo

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"

备注

可复制形式的输入(使用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)