【问题标题】:Simple moving average (partial window) of a vector using data.table in R使用 R 中的 data.table 对向量进行简单移动平均(部分窗口)
【发布时间】:2021-04-12 05:15:18
【问题描述】:

我有一个简单的向量如下:

x = c(14.24, 13.82, 12.75, 12.92, 12.94, 13.00, 14.14, 16.28, 20.64, 17.64)

我试图找到这个向量的滚动平均值并使用以下函数:

library(data.table)
y = frollmean(x, 5)

我得到的结果如下 -

 [1]     NA     NA     NA     NA 13.334 13.086 13.150 13.856 15.400 16.340

但是,我希望结果为 -

 [1]     14.24 14.03 13.06 13.43 13.334 13.086 13.150 13.856 15.400 16.340
  1. 第一个值应与原始向量中的相同
  2. 第二个值应该是第一个和第二个值的平均值
  3. 第三个值应该是初始三个值的平均值 向量
  4. 第四个值应该是向量中初始四个值的平均值

其余的计算由函数frollmean正确处理

任何建议都会有所帮助。

谢谢!

【问题讨论】:

    标签: r data.table rolling-computation


    【解决方案1】:

    在您的 frollmean 函数调用中,您要求窗口宽度为 5。由于没有足够的元素,因此无法针对此窗口宽​​度计算所有 NA 的前导元素。部分窗口支持在?frollmean 手动示例中提供。下面是根据您的案例改编的代码。

    x = c(14.24, 13.82, 12.75, 12.92, 12.94, 13.00, 14.14, 16.28, 20.64, 17.64)
    library(data.table)
    an = function(n, len) c(seq.int(n), rep(n, len-n))
    y = frollmean(x, an(5, length(x)), adaptive=TRUE)
    y
    # [1] 14.24000 14.03000 13.60333 13.43250 13.33400 13.08600 13.15000 13.85600 15.40000 16.34000
    

    参数adaptive 是更通用的(不仅仅是逻辑partial)自定义窗口宽度的方法。这里我们使用辅助函数an 来计算窗口的自适应长度。如果您只调用an,您可以观察到窗口宽度现在正是您预期的那样,而不是 5:

    an(5, length(x))
    # [1] 1 2 3 4 5 5 5 5 5 5
    

    【讨论】:

      【解决方案2】:

      您可以将zoorollapplyr 函数与partial = TRUE 一起使用。

      zoo::rollapplyr(x, 5, mean, partial = TRUE)
      #[1] 14.24 14.03 13.60 13.43 13.33 13.09 13.15 13.86 15.40 16.34
      

      【讨论】:

      • 我尝试在 TTR 库的 EMA 函数上运行相同的函数,但它给出了错误。 zoo::rollapplyr(x, 5, EMA, partial = TRUE)你知道怎么解决吗?我认为 EMA 函数已经有滚动窗口,但它没有任何设置部分的选项,如 zoo::rollapplyr
      • 我没有使用过EMA 函数,但是它有自己的窗口长度。所以我认为你不应该在rollapplyr函数中使用它。
      • 作为后续问题,我在这里发布了一个问题-stackoverflow.com/questions/65597909/…
      【解决方案3】:

      如果您想将该功能包含在您的 base R 武器库中,请将其放入您的 ~/.Rprofile

      rollmean <- function(vec, len, prtl = FALSE) {
        if (len > length(vec)) {
          stop(paste("Choose lower range,", len, ">", length(vec)))
        }
        else {
          if (prtl == T) {
            sapply(1:length(vec), function(i) {
              if (i <= len) {
                mean(vec[1:i])
              }
              else {
                mean(vec[(i - (len - 1)):i])
              }
            })
          }
          else {
            sapply(1:length(vec), function(i) {
              if (i - (len - 1) > 0) {
                mean(vec[(i - (len - 1)):i])
              }
              else {
                NA
              }
            })
          }
        }
      }
      
      x <- c(14.24, 13.82, 12.75, 12.92, 12.94, 13.00, 14.14, 16.28, 20.64, 17.64)
      
      rollmean( x, 5 )
      #[1]     NA     NA     NA     NA 13.334 13.086 13.150 13.856 15.400 16.340
      
      rollmean( x, 5, T )
      #[1] 14.24000 14.03000 13.60333 13.43250 13.33400 13.08600 13.15000 13.85600
      #[9] 15.40000 16.34000
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-21
        • 2020-08-13
        • 1970-01-01
        • 1970-01-01
        • 2021-04-12
        • 2023-03-12
        • 2014-07-12
        • 2016-05-26
        相关资源
        最近更新 更多