我正在计算3个月窗口内矢量的移动平均值。我想在下面的数据框中添加另一列,在窗口中折叠数月。所以在下面的例子中:
library(lubridate)
df <- data.frame(Date = seq(as.Date("2000/1/1"), by = "month", length.out = 12), x = rnorm(12))
df$month <- month(df$Date, abbr = TRUE, label = TRUE)
df$moving_x <- as.numeric(stats::filter(df$x,rep(1/3,3), sides=2))
现在df[2,]
,我得到以下内容:
> df[2,]
Date x month moving_x
2 2000-02-01 0.07902587 Feb -0.008438176
我想得到的是
> df[2,]
Date x month moving_x month_window
2 2000-02-01 0.07902587 Feb -0.008438176 Jan-Feb-Mar
所以我的问题是,是否有人可以推荐一种创建month_window
的好方法,即计算移动平均线的范围?我更喜欢只使用基础R的解决方案。
答案 0 :(得分:3)
以下是一些解决方案:
1)rollapply 在rollapply
和x
上使用month
及相关例程,如下所示:
library(zoo)
transform(df, moving_x = rollmean(x, 3, fill = NA),
month_window = rollapply(month, 3, paste, collapse = "-", fill = NA))
,并提供:
Date x month moving_x month_window
1 2000-01-01 0.37963948 Jan NA <NA>
2 2000-02-01 -0.50232345 Feb -0.1519638 Jan-Feb-Mar
3 2000-03-01 -0.33320738 Mar -0.6180354 Feb-Mar-Apr
4 2000-04-01 -1.01857538 Apr -0.8078580 Mar-Apr-May
5 2000-05-01 -1.07179123 May -0.5956127 Apr-May-Jun
6 2000-06-01 0.30352864 Jun -0.1066843 May-Jun-Jul
7 2000-07-01 0.44820978 Jul 0.2682475 Jun-Jul-Aug
8 2000-08-01 0.05300423 Aug 0.4744938 Jul-Aug-Sep
9 2000-09-01 0.92226747 Sep 1.0084521 Aug-Sep-Oct
10 2000-10-01 2.05008469 Oct 0.8271070 Sep-Oct-Nov
11 2000-11-01 -0.49103117 Nov -0.2500385 Oct-Nov-Dec
12 2000-12-01 -2.30916888 Dec NA <NA>
2)base 如果没有软件包,它会更复杂,但您可以隐藏函数roll3
中增加的复杂性,如下所示:
roll3 <- function(x, FUN, ...) {
if (length(x) < 3) {
rep(NA, length(x))
} else c(NA, apply(embed(x, 3)[, 3:1], 1, FUN, ...), NA)
}
transform(df, moving_x = roll3(x, mean),
month_window = roll3(as.character(month), paste, collapse = "-"))
,并提供:
Date x month moving_x month_window
1 2000-01-01 0.37963948 Jan NA <NA>
2 2000-02-01 -0.50232345 Feb -0.1519638 Jan-Feb-Mar
3 2000-03-01 -0.33320738 Mar -0.6180354 Feb-Mar-Apr
4 2000-04-01 -1.01857538 Apr -0.8078580 Mar-Apr-May
5 2000-05-01 -1.07179123 May -0.5956127 Apr-May-Jun
6 2000-06-01 0.30352864 Jun -0.1066843 May-Jun-Jul
7 2000-07-01 0.44820978 Jul 0.2682475 Jun-Jul-Aug
8 2000-08-01 0.05300423 Aug 0.4744938 Jul-Aug-Sep
9 2000-09-01 0.92226747 Sep 1.0084521 Aug-Sep-Oct
10 2000-10-01 2.05008469 Oct 0.8271070 Sep-Oct-Nov
11 2000-11-01 -0.49103117 Nov -0.2500385 Oct-Nov-Dec
12 2000-12-01 -2.30916888 Dec NA <NA>
另请注意,问题本身使用的是包。这个月可以这样获得:
df$month <- format(df$Date, "%b")
答案 1 :(得分:1)
如果您想要一个唯一的基础R解决方案,您可以使用sapply
:
df$window <- sapply(1:nrow(df),function(x) paste(df$month[x-1],
df$month[x],
df$month[x+1],sep="-"))
如果你不喜欢开头和结尾的行为,你可以ifelse
无效地点的功能