【发布时间】:2023-04-08 11:21:01
【问题描述】:
我一直在R中构建一个居中移动平均的函数(不使用任何包),遇到了如下挑战:
如您所知,居中移动平均线包含合并“不完整部分”的概念(即在数据点的开头和结尾处)。例如,考虑下面的向量p:
p <- c(10,20,30,40,50,60,70,80,90)
在这种情况下,我感兴趣的居中移动平均线如下所示:
x <- ((10+20)/2, (10+20+30)/3, (20+30+40)/3 ..... (70+80+90)/3, (80+90)/2)
为了实现上述目的,我尝试了以下 if 函数:
wd 表示window size
mov_avg <- function(p, wd) {
x <- c(0, cumsum(p))
if ((p > p[1])&(p < p[length(p)])) {
neut <- 1:(length(p)-(wd-1))
upper <- neut+(wd-1)
x <- (x[upper]-x[neut])/(upper-neut)
} else if (p==p[1]) {
neut <- 0
upper <- neut+3
x <- (x[upper]-x[neut])/(upper-1-neut)
} else if (p==p[length(p)]) {
upper <-(length(p)+1)
neut <- (length(p)-(wd-2))
x <- (x[upper]-x[neut])/(upper-neut)
}
return(x)
}
然后我进入下面一行执行:
mov_avg(p, 3)
我遇到了如下错误:
numeric(0)
Warning messages:
1: In if ((p > p[1]) & (p < p[length(p)])) { :
the condition has length > 1 and only the first element will be used
2: In if (p == p[1]) { :
the condition has length > 1 and only the first element will be used
有人可以帮我把它变成一个工作函数吗?
谢谢!
【问题讨论】:
-
您的警告来自您在
if()中比较的事实 - 将整个向量p与单个值进行比较。所以你需要在那里进行一些调整。实际上,你想在那里测试什么,或者换句话说,你试图在那里捕捉的三个案例是什么?不确定和口味不同,但我也认为 cumsum 可能不是实现目标的最简单方法。 -
非常感谢丹尼尔的评论。我正在尝试在时间序列上制作事件的概率轨迹,并正在开发几种不同的移动平均模型,包括这个。其他将是 TMA(三角移动平均线)和 EMA(指数移动平均线)..
-
对不起,这可能是一个误解,我的意思是你的三个 if-case 是什么?对我来说,这似乎有点像,当你在“中间”时,第一个应该去拿箱子,而另外两个应该在你在边境的时候去拿箱子?!但这行不通,因为您只需在函数中遍历整个内容,然后创建一个
x-vector。因此,如果您仍想使用您的函数(而不是已经建议的解决方案),我认为您仍然需要围绕 if 子句进行循环,然后您需要组合输出而不是仅仅覆盖它。 -
是的,丹尼尔,这就是我想做的……你明白了。另外,我知道我需要创建一个循环。我会试试看。 :) 再次感谢!
-
也许只是为了完成,你也可以看看这个旧线程stackoverflow.com/questions/743812/calculating-moving-average
标签: r moving-average