### 问题

how to get two sided "moving average" that is a function that averages n numbers from right and left of a vector and gives them weights according to their distance from center value ?

I tried to use TTR but its moving averages works only from left to right and set leftmost values as NA. So I cannot use that smoothed vector as a input to smooth.spline

### 回答1:

In the zoo package `rollmean`

and `rollapply`

have arguments that allow numerous variations.

```
library(zoo)
x <- seq(10)^2
# no NAs at end
rollmean(x, 3)
# NAs at ends
rollmean(x, 3, na.pad = TRUE)
# weighted mean
rollapply(zoo(x), 3, function(x) c(1, 2, 1) %*% x / 4)
# at ends take means of less than 3 points - needs devel version
# partial= is in development and at this point must use na.rm = TRUE to use partial
source("http://r-forge.r-project.org/scm/viewvc.php/*checkout*/pkg/zoo/R/rollapply.R?revision=802&root=zoo")
rollapply(zoo(x), 3, mean, partial = TRUE, na.rm = TRUE)
```

EDIT:

Note that since this was written the development version of zoo was changed so that instead of writing `partial = TRUE`

one writes rule = "partial" or `rule = 3`

. The problem was that as new end rules were added to the development version (there are now 3 and a 4th will be added before its released) having a separate argument for each one clutters the user interface. Also `rule`

is more consistent with `approx`

in the core of R. In fact, `rule=1`

and `rule=2`

will have the same meaning in `rollapply`

and in `approx`

(from the core of R) for better consistency and ease of use. The parentheses around `mean`

in the example below are currently required in the development version to prevent it from calling `rollmean`

, where `rule="partial"`

has not yet been implemented, but the need to do that will be eliminated by the time its officially released.

```
source("http://r-forge.r-project.org/scm/viewvc.php/*checkout*/pkg/zoo/R/rollapply.R?revision=815&root=zoo")
rollapply(zoo(x), 3, (mean), rule = "partial")
```

### 回答2:

Look at the `filter()`

function, and particularly the `sides`

argument:

`filter package:stats R Documentation Linear Filtering on a Time Series Description: Applies linear filtering to a univariate time series or to each series separately of a multivariate time series. Usage: filter(x, filter, method = c("convolution", "recursive"), sides = 2, circular = FALSE, init) Arguments: [...] sides: for convolution filters only. If ‘sides=1’ the filter coefficients are for past values only; if ‘sides=2’ they are centred around lag 0. In this case the length of the filter should be odd, but if it is even, more of the filter is forward in time than backward.`

### 回答3:

You could try kernel together with kernapply (there are some examples towards the end of the first page).

来源：`https://stackoverflow.com/questions/4418643/two-sided-moving-average`