题
我正在尝试使用 R 计算矩阵中一系列值的移动平均值。不过,普通的 R 邮件列表搜索并没有多大帮助。似乎没有一个 内置功能 在 R 中,我可以计算移动平均线。有任何套餐提供吗?还是我需要自己写?
其他提示
或者你可以简单地计算出它使用过滤器,这是我使用的功能:
ma <- function(x, n = 5){filter(x, rep(1 / n, n), sides = 2)}
如果您使用dplyr
,小心在上面的函数来指定stats::filter
。
使用cumsum
应该足够和有效的。假设你有一个矢量 X 和要名词的数字的运行总和
cx <- c(0,cumsum(x))
rsum <- (cx[(n+1):length(cx)] - cx[1:(length(cx) - n)]) / n
如通过@mzuther的评论所指出的,这是假定有在数据中没有的NA。处理那些需要通过非NA值的数量除以每个窗口。下面是这样做的,结合了来自@Ricardo克鲁兹评论的一种方式:
cx <- c(0, cumsum(ifelse(is.na(x), 0, x)))
cn <- c(0, cumsum(ifelse(is.na(x), 0, 1)))
rx <- cx[(n+1):length(cx)] - cx[1:(length(cx) - n)]
rn <- cn[(n+1):length(cx)] - cn[1:(length(cx) - n)]
rsum <- rx / rn
这仍然有问题,如果在窗口中的所有值均为的NA那么就会出现被零除错误。
在的 data.table 1.12.0 新frollmean
功能已被添加到计算快速和精确轧制仔细意味着处理NA
,NaN
和+Inf
,-Inf
值。
如存在的问题没有重复的例子,有没有更多在这里讨论。
您可以找到有关手册?frollmean
的详细信息,也可在网上的 ?frollmean
。
从手动下面的实施例:
library(data.table)
d = as.data.table(list(1:6/2, 3:8/4))
# rollmean of single vector and single window
frollmean(d[, V1], 3)
# multiple columns at once
frollmean(d, 3)
# multiple windows at once
frollmean(d[, .(V1)], c(3, 4))
# multiple columns and multiple windows at once
frollmean(d, c(3, 4))
## three above are embarrassingly parallel using openmp
在caTools
包已经非常快的滚动平均值/最小/最大/ SD和几个其他功能。我只用runmean
和runsd
工作,他们是最快的任何提及迄今为止其它软件包。
您可以使用RcppRoll
为C ++编写的非常快的移动平均线。只需调用roll_mean
功能。文档可以发现这里。
否则,此(更慢)的for循环应该做的伎俩:
ma <- function(arr, n=15){
res = arr
for(i in n:length(arr)){
res[i] = mean(arr[(i-n):i])
}
res
}
在事实上RcppRoll
是非常好的。
张贴由 cantdutchthis 代码必须在第四行到窗口来校正被固定:
ma <- function(arr, n=15){
res = arr
for(i in n:length(arr)){
res[i] = mean(arr[(i-n+1):i])
}
res
}
另一种方法,它处理missings,给出此处。
第三种方法,提高 cantdutchthis 代码来计算部分平均值与否,如下:
ma <- function(x, n=2,parcial=TRUE){
res = x #set the first values
if (parcial==TRUE){
for(i in 1:length(x)){
t<-max(i-n+1,1)
res[i] = mean(x[t:i])
}
res
}else{
for(i in 1:length(x)){
t<-max(i-n+1,1)
res[i] = mean(x[t:i])
}
res[-c(seq(1,n-1,1))] #remove the n-1 first,i.e., res[c(-3,-4,...)]
}
}
moving_fun <- function(x, w, FUN, ...) {
# x: a double vector
# w: the length of the window, i.e., the section of the vector selected to apply FUN
# FUN: a function that takes a vector and return a summarize value, e.g., mean, sum, etc.
# Given a double type vector apply a FUN over a moving window from left to the right,
# when a window boundary is not a legal section, i.e. lower_bound and i (upper bound)
# are not contained in the length of the vector, return a NA_real_
if (w < 1) {
stop("The length of the window 'w' must be greater than 0")
}
output <- x
for (i in 1:length(x)) {
# plus 1 because the index is inclusive with the upper_bound 'i'
lower_bound <- i - w + 1
if (lower_bound < 1) {
output[i] <- NA_real_
} else {
output[i] <- FUN(x[lower_bound:i, ...])
}
}
output
}
# example
v <- seq(1:10)
# compute a MA(2)
moving_fun(v, 2, mean)
# compute moving sum of two periods
moving_fun(v, 2, sum)
虽然有点慢,但也可以使用动物园:: rollapply对矩阵执行计算。
reqd_ma <- rollapply(x, FUN = mean, width = n)
其中,x是所述数据集,FUN =平均值的函数;还可以将其改变为最小值,最大值,SD等和宽度是滚动窗口。