dplyr 动态创建滞后和 ma 特征

Posted

技术标签:

【中文标题】dplyr 动态创建滞后和 ma 特征【英文标题】:dplyr dynamically create lag and ma features 【发布时间】:2021-12-06 18:27:25 【问题描述】:

我正在尝试创建一个接收数据框并创建其他滞后和滚动窗口功能(例如移动平均线)的流程。这是我目前所拥有的。

# dummy dataframe
n <- 20
set.seed(123)
foo <- data.frame(
  date = seq(as.Date('2020-01-01'),length.out = n, by = 'day'),
  var1 = sample.int(n),
  var2 = sample.int(n))

# creates lags and based on (some of) them creates rolling average features
foo %>% 
  mutate_at(vars(starts_with('var')),
            funs(lag_1 = lag(.), lag_2 = lag(.,2))) %>% 
  mutate_at(vars(contains('lag_1')),
            funs(ra_3 = rollmean(., k = 3, align = 'right', fill = NA)))

上面的块:

    根据所选变量创建 lag01、lag02 特征 基于新创建的列的子集,创建滚动平均特征

我现在正在寻找的是创建任意数量的滞后特征(例如 lag3、lag6、lag9 等)以及创建任意数量的滚动平均特征(具有不同的窗口长度 - 即 var1_lag_1_ra_3、var1_lag_1_ra_6 , var2_lag_1_ra_3, var2_lag_1_ra_6。目前生成此类特征的设置是硬编码的。理想情况下,我会有几个向量来调整结果;像这样:

lag_features <- c(3,6,9)
ma_features <- c(12,15)

最后,如果有办法以动态方式配置生成的特征的名称,那就太好了。我见过,!!,:= 运算符,但我真的无法区分它们或如何使用它们。

我还使用 timetk 包中的一些现成的功能实现了上述功能,但由于我正在寻找一些额外的灵活性,我想知道如何自己复制这种行为。

library(timetk)
foo %>% 
  select(date,starts_with('var')) %>%
  tk_augment_lags(.value = starts_with("var"),
                  .lags = 1) %>% 
  tk_augment_slidify(.value   = ends_with("lag1"),
                     .period  = seq(0,24,3)[-1],
                     .f       = mean,
                     .align   = 'right', 
                     .partial = TRUE
  )

非常感谢任何支持。

【问题讨论】:

请注意:mutate_at 已过时。请改用 mutateacross 结合使用。 :-) 你说的很对,我也测试过,仍然无法克服硬编码foo %&gt;% select(contains('var')) %&gt;% mutate(across(starts_with('var'), list(lag01 = lag, lag02 = ~lag(.,2)))) 说实话:你的问题我看了两遍,我还是不明白你在做什么。 例如说我需要创建 c(1,2,3,6,12,24) 滞后 - 跨越选定的变量 - 然后创建 c(3,6,12, 24) 窗口长度 - 基于 lag1 和选定的变量 - 无需每次都手动调整代码。这就是为什么我需要以某种方式从硬编码值转向更灵活/动态的方式来创建上述内容..现在更清楚了吗? 【参考方案1】:

您可以使用map 函数来获取变量数字的滞后值。我们可以使用across 中的.names 参数为新列提供名称。

library(dplyr)
library(purrr)
library(zoo)

lag_features <- c(3,6,9)
ma_features <- c(12,15)

foo <- bind_cols(foo, map_dfc(lag_features, ~foo %>% 
                         transmute(across(starts_with('var'), 
                                          lag, .x, .names = 'col_lag.x'))),
                map_dfc(ma_features, ~foo %>%
                        transmute(across(contains('lag3'), rollmeanr, k = .x, 
                             fill = NA, .names = 'col_.x'))))

【讨论】:

很好的解决方案,非常感谢!无论如何,您是否有任何替代方案不需要两个单独的分配 - 换句话说,使上述所有事情在一个步骤中发生? 是的,当然..查看更新的答案。

以上是关于dplyr 动态创建滞后和 ma 特征的主要内容,如果未能解决你的问题,请参考以下文章

如何根据用户输入创建动态 CSS

按 dplyr 中的动态列名汇总

r/dplyr:在 UDF 中使用动态命名的变量

dplyr 滞后与列值中的 n

dplyr case_when具有动态案例数时

使用带有动态渲染项目的 UIScrollView 消除滚动滞后