我一直在构建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
有人可以帮我实现这一功能吗?
谢谢!
答案 0 :(得分:2)
在基数R中这样的事情怎么样:
window <- 3
p <- c(10,20,30,40,50,60,70,80,90)
x <- c(NA, p, NA)
sapply(seq_along(x[-(1:(window - 1))]), function(i)
mean(x[seq(i, i + window - 1)], na.rm = T))
#[1] 15 20 30 40 50 60 70 80 85
技巧是添加侧翼NA
,然后将mean
与na.rm = T
一起使用。
我知道您说的是“不使用软件包”,但是使用zoo::rollapply
library(zoo)
rollapply(c(NA, p, NA), 3, mean, na.rm = T)
#[1] 15 20 30 40 50 60 70 80 85
答案 1 :(得分:2)
我们也可以使用rowMeans
rowMeans(embed(c(NA, p, NA), 3)[, 3:1], na.rm = TRUE)
#[1] 15 20 30 40 50 60 70 80 85
答案 2 :(得分:1)
另一种方法是创建一个函数,我们可以用变量window
s进行调整
mov_avg <- function(p, window) {
mean_number = numeric()
index = 1
while(index < length(p)) {
if (index == 1 | index == length(p) - 1)
mean_number = c(mean_number, mean(p[index:(index + window - 2)]))
else
mean_number = c(mean_number, mean(p[index:(index + window - 1)]))
index = index + 1
}
mean_number
}
mov_avg(p, 3)
#[1] 15 30 40 50 60 70 80 85
mov_avg(p, 2)
#[1] 10 25 35 45 55 65 75 80
答案 3 :(得分:1)
在矩阵中按行取均值为x的列,并在头和尾分别附加前两个元素和后两个元素的均值。
apply( matrix( c(x,
c( x[1]+x[2])/2, head(x,-1) ),
c( tail(x,-1), sum( tail(x,2))/2) ),
ncol = 3),
1, mean)