首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >只使用R的基础编写状态窗口函数

只使用R的基础编写状态窗口函数
EN

Stack Overflow用户
提问于 2014-04-28 20:17:08
回答 2查看 165关注 0票数 0

我正在尝试编写R代码,它充当一个“移动窗口”,只是使用内存(状态)。我已经知道(多亏了this question)如何将函数应用到元素的后续元组中。例如,如果我希望编写一个(简单的)移动平均线,并具有典型的周期4,我将执行以下操作:

代码语言:javascript
复制
mapply(myfunc, x[1:(length(x)-4)], x[2:(length(x)-3)], x[3:(length(x)-2)], x[4:(length(x)-1)])

其中myfunc是一个带有4个参数的函数,它计算它们的平均值(我不能使用mean,因为它只需要一个参数,而且我不知道如何使这4个参数成为一个向量)。但是,这是相当麻烦的,如果典型的周期是100,比如说,我不知道怎么做。

这是我的第一个问题:我如何概括这一点?

但这里还有另一个问题:假设我希望应用的函数能够保存状态。一个简单的例子是记录到目前为止它应用于多少个值。另一个例子是指数移动平均(EMA),它实际上不是一个窗口函数,而是一个作用于单个值但保持状态的函数(最后一个结果是平均值)。

我如何编写一个函数,当它应用于一个向量时,一个地处理它的值,返回一个长度相同的向量,它每次都能保留它的最后一个输出,或者在计算过程中保存任何其他的“状态”?例如,在Python中,我会为此使用类,但在R中这是相当困难的。

重要注意事项:,我对辅助R包(如zooTTR )不感兴趣,为我做这项工作。我正在努力学习R,无论如何,我想编写的函数虽然与MAEMA有相似之处,但它们都是自定义的,并且在这些包中都不存在。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-28 20:34:36

关于你的第一个问题,

代码语言:javascript
复制
n <- length(x)
k <- 4
r <- embed(x, n-k)[1:k, seq(n-k, 1)]
do.call("mapply", c("myfunc", split(r, 1:k)))

关于第二个问题,可以使用Reduce迭代向量保存状态。

票数 3
EN

Stack Overflow用户

发布于 2014-04-28 21:16:44

对于这种情况,您应该考虑使用普通的for循环:

代码语言:javascript
复制
x <- runif(10000)
k <- 100
n <- length(x)
res <- numeric(n - k)

library(microbenchmark)
microbenchmark(times=5,
  for(i in k:n) res[i - k + 1] <- sum(vec[i:(i + k)]),
  {
    r <- embed(x, n-k)[1:k, seq(n-k, 1)]
    gg <- do.call("mapply", c("sum", split(r, 1:k)))    
  },
  flt <- filter(x, rep(1, k))
)

生产:

代码语言:javascript
复制
Unit: milliseconds
                    min        lq    median        uq       max neval
for            163.5403  164.4929  165.2543  166.6315  167.0608     5
embed/mapply  1255.2833 1307.3708 1338.2748 1341.5719 1405.1210     5
filter           6.7101    6.7971    6.8073    6.8161    6.8991     5

现在,结果是不一样的,我并不假装完全理解GGrothendieck对embed所做的事情,但是一般来说,只要先初始化结果向量,for循环就和*pply函数一样快。加窗口的计算不能很好地用于向量化,所以最好使用for循环。

编辑:正如一些人在评论中指出的那样,似乎有一个内部实现的函数要做(filter) --这要快得多,所以这似乎是最好的选择(尽管您应该再次确认它实际上做了您想做的事情,但是结果并不完全相同,而且我个人不太熟悉这个函数;在它的默认配置中,它似乎做了一个滚动加权和,或者如果权重是1,则使用居中窗口)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23350408

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档