我试着用R来计算矩阵中一系列值的移动平均值。R中似乎没有一个内置函数可以让我计算移动平均线。有任何软件包提供这样的服务吗?还是需要我自己写?
当前回答
在数据。表1.12.0增加了新的滚动平均值函数,以计算快速和准确的滚动平均值,仔细处理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
其他回答
或者你可以简单地计算它使用过滤器,这是我使用的函数:
ma <- function(x, n = 5){filter(x, rep(1 / n, n), sides = 2)}
如果使用dplyr,请注意在上面的函数中指定stats::filter。
动物园包中的滚动平均值/最大值/中位数(rollmean) TTR中的移动平均线 马云在预测
使用费用应充分、有效。假设你有一个向量x,你想要n个数的和
cx <- c(0,cumsum(x))
rsum <- (cx[(n+1):length(cx)] - cx[1:(length(cx) - n)]) / n
正如@mzuther在评论中指出的那样,这假设数据中没有NAs。要处理这些问题,需要将每个窗口除以非na值的数量。这里有一种方法,结合@里卡多·克鲁兹的评论:
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
这仍然有一个问题,如果窗口中的所有值都是NAs,那么将会有一个零误差的除法。
vector_avg <- function(x){
sum_x = 0
for(i in 1:length(x)){
if(!is.na(x[i]))
sum_x = sum_x + x[i]
}
return(sum_x/length(x))
}
滑块包可以用于此。它有一个专门设计的界面,感觉类似呜呜声。它接受任何任意函数,并可以返回任何类型的输出。数据帧甚至按行迭代。pkgdown网站在这里。
library(slider)
x <- 1:3
# Mean of the current value + 1 value before it
# returned as a double vector
slide_dbl(x, ~mean(.x, na.rm = TRUE), .before = 1)
#> [1] 1.0 1.5 2.5
df <- data.frame(x = x, y = x)
# Slide row wise over data frames
slide(df, ~.x, .before = 1)
#> [[1]]
#> x y
#> 1 1 1
#>
#> [[2]]
#> x y
#> 1 1 1
#> 2 2 2
#>
#> [[3]]
#> x y
#> 1 2 2
#> 2 3 3
滑块和数据的开销。Table的frollapply()应该非常低(比zoo快得多)。对于这个简单的示例,Frollapply()看起来稍微快一些,但请注意,它只接受数字输入,并且输出必须是标量数值。滑块函数是完全通用的,你可以返回任何数据类型。
library(slider)
library(zoo)
library(data.table)
x <- 1:50000 + 0L
bench::mark(
slider = slide_int(x, function(x) 1L, .before = 5, .complete = TRUE),
zoo = rollapplyr(x, FUN = function(x) 1L, width = 6, fill = NA),
datatable = frollapply(x, n = 6, FUN = function(x) 1L),
iterations = 200
)
#> # A tibble: 3 x 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 slider 19.82ms 26.4ms 38.4 829.8KB 19.0
#> 2 zoo 177.92ms 211.1ms 4.71 17.9MB 24.8
#> 3 datatable 7.78ms 10.9ms 87.9 807.1KB 38.7