R 计算移动平均线

R 计算移动平均线,r,moving-average,r-faq,R,Moving Average,R Faq,我试图用R来计算矩阵中一系列值的移动平均值。不过,普通的R邮件列表搜索并没有太大帮助。在R中似乎没有a,这将允许我计算移动平均线。有没有套餐提供?还是我需要自己写? 包中的滚动平均值/最大值/中间值(滚动平均值) 移动公寓 马因 或者您可以简单地使用过滤器进行计算,以下是我使用的函数: ma <- function(x, n = 5){filter(x, rep(1 / n, n), sides = 2)} macaTools包具有非常快速的滚动平均值/min/max/sd和很少的其他功

我试图用R来计算矩阵中一系列值的移动平均值。不过,普通的R邮件列表搜索并没有太大帮助。在R中似乎没有a,这将允许我计算移动平均线。有没有套餐提供?还是我需要自己写?

  • 包中的滚动平均值/最大值/中间值(滚动平均值)
  • 移动公寓
  • 马因

或者您可以简单地使用过滤器进行计算,以下是我使用的函数:

ma <- function(x, n = 5){filter(x, rep(1 / n, n), sides = 2)}

macaTools
包具有非常快速的滚动平均值/min/max/sd和很少的其他功能。我只使用了<>代码> RunMedie/Cuff>和 RunSD,它们是迄今为止提到的所有其他包中最快的。

< P>可以用<代码> RCPPROLL>代码>用于C++编写的非常快的移动平均值。只需调用
roll\u mean
函数。可以找到文档

否则,这个(较慢的)for循环应该可以:

ma <- function(arr, n=15){
  res = arr
  for(i in n:length(arr)){
    res[i] = mean(arr[(i-n):i])
  }
  res
}

ma使用
cumsum
应该足够有效。假设你有一个向量x,你想要一个n个数的运行和


cx事实上
RcppRoll
非常好

必须在窗口的第四行更正张贴的代码:

ma <- function(arr, n=15){
  res = arr
  for(i in n:length(arr)){
    res[i] = mean(arr[(i-n+1):i])
  }
  res
}

ma以补充和的答案


虽然移动有点慢,但您也可以使用zoo::rollapply对矩阵执行计算

reqd_ma <- rollapply(x, FUN = mean, width = n)

requd_ma在数据中。表1.12.0添加了新的
frollmean
函数,以计算快速准确的滚动平均值,仔细处理
NA
NaN
+Inf
-Inf

由于在这个问题上没有可复制的例子,所以这里没有更多的问题需要解决

您可以在手册中找到有关
?frollmean
的更多信息,也可在线访问

以下手册中的示例:

库(data.table)
d=as.data.table(列表(1:6/2,3:8/4))
#单向量单窗口的均值
Frollman(d[,V1],3)
#一次多列
弗罗尔平均数(d,3)
#一次打开多个窗口
Frollman(d[,(V1)],c(3,4))
#一次多个列和多个窗口
弗罗尔平均值(d,c(3,4))
##使用openmp时,上面三个是令人尴尬的并行
可以使用软件包来移动功能。在这种情况下,
mean\u运行
功能。
cummean
的问题在于它不处理
NA
值,但
mean\u run
处理
runner
软件包还支持不规则的时间序列,窗口可能取决于日期:

库(运行程序)
种子(11)
x1[13]-0.3858234-0.3765192-0.42809
平均运行时间(x2,不适用rm=TRUE)
#>  [1] -0.18760011 -0.09022066 -0.06543317  0.03906450 -0.12188853 -0.13873536
#>  [7] -0.13873536 -0.14571604 -0.12596067 -0.11116961 -0.09881996 -0.08871569
#> [13] -0.05194292 -0.04699909 -0.05704202
平均运行时间(x2,不适用rm=FALSE)
#>  [1] -0.18760011 -0.09022066 -0.06543317  0.03906450 -0.12188853 -0.13873536
#>[7]不,不,不,不
#>[13]娜娜娜娜
平均运行时间(x2,不适用rm=TRUE,k=4)
#>  [1] -0.18760011 -0.09022066 -0.06543317  0.03906450 -0.10546063 -0.16299272
#>  [7] -0.21203756 -0.39209010 -0.13274756 -0.05603811 -0.03894684  0.01103493
#> [13]  0.09609256  0.09738460  0.04740283
平均运行时间(x2,na\u rm=TRUE,k=4,idx=date)
#> [1] -0.187600111 -0.090220655 -0.004349696  0.168349653 -0.206571573 -0.494335093
#> [7] -0.222969541 -0.187600111 -0.087636571  0.009742884  0.009742884  0.012326968
#> [13]  0.182442234  0.125737145  0.059094786

您还可以指定其他选项,如
lag
,并仅在
特定索引处滚动
。更多信息请参见和文档。

滑块包可用于此目的。它有一个专门设计的界面,感觉与purrr类似。它接受任何任意函数,并可以返回任何类型的输出。数据帧甚至按行进行迭代。pkgdown站点是

库(滑块)
x[1]1.01.52.5
df[[1]]
#>xy
#> 1 1 1
#> 
#> [[2]]
#>xy
#> 1 1 1
#> 2 2 2
#> 
#> [[3]]
#>xy
#> 1 2 2
#> 2 3 3
slider和data.table的
frollapply()
开销应该很低(比zoo快得多)
frollapply()
对于这个简单的示例来说似乎要快一点,但是请注意,它只接受数字输入,并且输出必须是标量数值。滑块函数是完全通用的,可以返回任何数据类型

库(滑块)
图书馆(动物园)
库(数据表)
x#A tibble:3 x 6
#>表达式最小中位数`itr/sec`mem_alloc`gc/sec`
#>               
#>1个滑块19.82ms 26.4ms 38.4 829.8KB 19.0
#>2动物园177.92ms 211.1ms 4.71 17.9MB 24.8
#>3数据表7.78ms 10.9ms 87.9 807.1KB 38.7

以下是示例代码,说明如何使用包中的
rollmean
函数计算居中移动平均线和尾随移动平均线

库(tidyverse)
图书馆(动物园)
一些数据=TIBLE(天=1:10)
#cma=居中移动平均线
#tma=尾随移动平均线
部分数据=部分数据%>%
突变(cma=rollmean(天,k=3,fill=NA))%>%
突变(tma=rollmean(天,k=3,fill=NA,align=“right”))
一些数据
#>#tibble:10 x 3
#>日cma tma
#>      
#>1纳纳
#>2不适用
#>  3     3     3     2
#>  4     4     4     3
#>  5     5     5     4
#>  6     6     6     5
#>  7     7     7     6
#>  8     8     8     7
#>  9     9     9     8
#>10 10 NA 9

vector\u avg编辑:非常高兴添加
参数,用于移动平均值(或总和,或…),例如
日期的过去7天
向量


对于那些只想自己计算的人来说,这没什么
ma <- function(arr, n=15){
  res = arr
  for(i in n:length(arr)){
    res[i] = mean(arr[(i-n+1):i])
  }
  res
}
  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)
reqd_ma <- rollapply(x, FUN = mean, width = n)
library(tidyverse)
library(zoo)

some_data = tibble(day = 1:10)
# cma = centered moving average
# tma = trailing moving average
some_data = some_data %>%
    mutate(cma = rollmean(day, k = 3, fill = NA)) %>%
    mutate(tma = rollmean(day, k = 3, fill = NA, align = "right"))
some_data
#> # A tibble: 10 x 3
#>      day   cma   tma
#>    <int> <dbl> <dbl>
#>  1     1    NA    NA
#>  2     2     2    NA
#>  3     3     3     2
#>  4     4     4     3
#>  5     5     5     4
#>  6     6     6     5
#>  7     7     7     6
#>  8     8     8     7
#>  9     9     9     8
#> 10    10    NA     9
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))
}
# x = vector with numeric data
# w = window length
y <- numeric(length = length(x))

for (i in seq_len(length(x))) {
  ind <- c((i - floor(w / 2)):(i + floor(w / 2)))
  ind <- ind[ind %in% seq_len(length(x))]
  y[i] <- mean(x[ind])
}

y
# our working horse:
moving_fn <- function(x, w, fun, ...) {
  # x = vector with numeric data
  # w = window length
  # fun = function to apply
  # side = side to take, (c)entre, (l)eft or (r)ight
  # ... = parameters passed on to 'fun'
  y <- numeric(length(x))
  for (i in seq_len(length(x))) {
    if (side %in% c("c", "centre", "center")) {
      ind <- c((i - floor(w / 2)):(i + floor(w / 2)))
    } else if (side %in% c("l", "left")) {
      ind <- c((i - floor(w) + 1):i)
    } else if (side %in% c("r", "right")) {
      ind <- c(i:(i + floor(w) - 1))
    } else {
      stop("'side' must be one of 'centre', 'left', 'right'", call. = FALSE)
    }
    ind <- ind[ind %in% seq_len(length(x))]
    y[i] <- fun(x[ind], ...)
  }
  y
}

# and now any variation you can think of!
moving_average <- function(x, w = 5, side = "centre", na.rm = FALSE) {
  moving_fn(x = x, w = w, fun = mean, side = side, na.rm = na.rm)
}

moving_sum <- function(x, w = 5, side = "centre", na.rm = FALSE) {
  moving_fn(x = x, w = w, fun = sum, side = side, na.rm = na.rm)
}

moving_maximum <- function(x, w = 5, side = "centre", na.rm = FALSE) {
  moving_fn(x = x, w = w, fun = max, side = side, na.rm = na.rm)
}

moving_median <- function(x, w = 5, side = "centre", na.rm = FALSE) {
  moving_fn(x = x, w = w, fun = median, side = side, na.rm = na.rm)
}

moving_Q1 <- function(x, w = 5, side = "centre", na.rm = FALSE) {
  moving_fn(x = x, w = w, fun = quantile, side = side, na.rm = na.rm, 0.25)
}

moving_Q3 <- function(x, w = 5, side = "centre", na.rm = FALSE) {
  moving_fn(x = x, w = w, fun = quantile, side = side, na.rm = na.rm, 0.75)
}
wma <- function(x) { 
  wts <- c(seq(0.5, 4, 0.5), seq(3.5, 0.5, -0.5))
  nside <- (length(wts)-1)/2
  # pad x with begin and end values for filter to avoid NAs
  xp <- c(rep(first(x), nside), x, rep(last(x), nside)) 
  z <- stats::filter(xp, wts/sum(wts), sides = 2) %>% as.vector 
  z[(nside+1):(nside+length(x))]
}
apply(embed(x, k), 1, mean)
v=1:1000*0.002+rnorm(1000)
mrng=rep(1:round(length(v)/60+0.5), length.out=length(v), each=60)
aggregate(v~mrng, FUN=mean, na.rm=T)