Calculating moving average

前端 未结 16 1764
夕颜
夕颜 2020-11-21 23:55

I\'m trying to use R to calculate the moving average over a series of values in a matrix. The normal R mailing list search hasn\'t been very helpful though. There doesn\'t s

相关标签:
16条回答
  • 2020-11-22 00:23

    Though a bit slow but you can also use zoo::rollapply to perform calculations on matrices.

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

    where x is the data set, FUN = mean is the function; you can also change it to min, max, sd etc and width is the rolling window.

    0 讨论(0)
  • 2020-11-22 00:27

    One can use runner package for moving functions. In this case mean_run function. Problem with cummean is that it doesn't handle NA values, but mean_run does. runner package also supports irregular time series and windows can depend on date:

    library(runner)
    set.seed(11)
    x1 <- rnorm(15)
    x2 <- sample(c(rep(NA,5), rnorm(15)), 15, replace = TRUE)
    date <- Sys.Date() + cumsum(sample(1:3, 15, replace = TRUE))
    
    mean_run(x1)
    #>  [1] -0.5910311 -0.2822184 -0.6936633 -0.8609108 -0.4530308 -0.5332176
    #>  [7] -0.2679571 -0.1563477 -0.1440561 -0.2300625 -0.2844599 -0.2897842
    #> [13] -0.3858234 -0.3765192 -0.4280809
    
    mean_run(x2, na_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
    
    mean_run(x2, na_rm = FALSE )
    #>  [1] -0.18760011 -0.09022066 -0.06543317  0.03906450 -0.12188853 -0.13873536
    #>  [7]          NA          NA          NA          NA          NA          NA
    #> [13]          NA          NA          NA
    
    mean_run(x2, na_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
    
    mean_run(x2, na_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
    

    One can also specify other options like lag, and roll only at specific indexes. More in package and function documentation.

    0 讨论(0)
  • 2020-11-22 00:32

    The caTools package has very fast rolling mean/min/max/sd and few other functions. I've only worked with runmean and runsd and they are the fastest of any of the other packages mentioned to date.

    0 讨论(0)
  • 2020-11-22 00:33

    In order to complement the answer of cantdutchthis and Rodrigo Remedio;

    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)
    
    0 讨论(0)
  • 2020-11-22 00:36

    In data.table 1.12.0 new frollmean function has been added to compute fast and exact rolling mean carefully handling NA, NaN and +Inf, -Inf values.

    As there is no reproducible example in the question there is not much more to address here.

    You can find more info about ?frollmean in manual, also available online at ?frollmean.

    Examples from manual below:

    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
    
    0 讨论(0)
  • 2020-11-22 00:37

    You could use RcppRoll for very quick moving averages written in C++. Just call the roll_mean function. Docs can be found here.

    Otherwise, this (slower) for loop should do the trick:

    ma <- function(arr, n=15){
      res = arr
      for(i in n:length(arr)){
        res[i] = mean(arr[(i-n):i])
      }
      res
    }
    
    0 讨论(0)
提交回复
热议问题