对xts对象和匿名定义的函数使用rollapply

时间:2018-12-11 04:00:04

标签: r apply

我正在尝试在向下滑动xts数据框的列的窗口上使用rollapply创建滚动计算。例如,假设我定义了一个xts对象:

df1 <- data.frame(A = c(1,2,3,4,5,6,7,8,9),
              B = c(3,4,5,6,7,8,9,10,11))
dfxts <- xts(df1, order.by = as.Date(c(30,31,32,33,34,35,36,37,38)))

这提供了xts功能:

           A  B
1970-01-31 1  3
1970-02-01 2  4
1970-02-02 3  5
1970-02-03 4  6
1970-02-04 5  7
1970-02-05 6  8
1970-02-06 7  9
1970-02-07 8 10
1970-02-08 9 11

据我所知width参数,它定义了进行某些操作(例如,平均值操作)的滑动窗口的长度(尽管我不清楚'width')。

说,我想在宽度为3的窗口上创建滚动操作,在该窗口上的每个位置添加窗口的第二和第三元素。我想在窗口的每个位置添加x(2)+ x(3)。我会得到:

           A  B
1970-01-31 NA NA
1970-02-01 NA NA
1970-02-02 5  9
1970-02-03 7  11
1970-02-04 9  13
1970-02-05 11 15
1970-02-06 13 17
1970-02-07 15 19
1970-02-08 17 21

我尝试通过以下方式实现此目标

 rollapply(dfxts, width = 3, FUN=function(x) x(2)+x(3), align = "right")

我得到了错误:

  

“包装时出错:找不到函数“ x”

我想我误会了如何使用rollapply,如何实现匿名功能或两者。

2 个答案:

答案 0 :(得分:1)

我不确定是否可以将rollapply应用于整个数据框。您可以使用lapply将其分别应用于每一列,并且由于您希望第二和第三元素中的sum可以将width减少为2

library(zoo)
lapply(dfxts, function(x) rollapply(x, width = 2, FUN=sum))


#$A
#            A
#1970-01-31 NA
#1970-02-01  3
#1970-02-02  5
#1970-02-03  7
#1970-02-04  9
#1970-02-05 11
#1970-02-06 13
#1970-02-07 15
#1970-02-08 17

#$B
#            B
#1970-01-31 NA
#1970-02-01  7
#1970-02-02  9
#1970-02-03 11
#1970-02-04 13
#1970-02-05 15
#1970-02-06 17
#1970-02-07 19
#1970-02-08 21

如果由于某种原因您只能将width保留为3并且不能更改它,那么我们可以做到

lapply(dfxts, function(x) rollapply(x, width = 3, FUN=function(y) sum(y[2],y[3])))

将给出相同的输出,除了前两个值将是NA而不是一个。


编辑

如评论中所述,要应用的实际功能要比所呈现的功能复杂得多,这将需要使用自定义功能而不是内置功能,我们可以使用coredata来获取实际数据并然后相应地应用我们的功能。

所以在给定的示例中,我们可以做到

rollapply(dfxts, width = 3, FUN=function(x) coredata(x[2]) +  coredata(x[3]))

但是,对于更通用的方法,我们只能调用coredata一次,然后按需要使用它们。因此,如果我们要应用操作5*x(5) - 8*x(7) + x(15),可以这样做

rollapply(dfxts, width = 15, FUN=function(x) {
          vals <- coredata(x)
          5*vals[5] - 8*vals[7] + vals[15]
})

答案 1 :(得分:1)

只需稍微更改一下滚动应用即可(sum(x[2],x[3])而不是x(2)+x(3)),它可以起作用:

rollapply(dfxts, width = 3, FUN=function(x) sum(x[2],x[3]), align = "right")

这是我得到的输出:

#            A  B
#1970-01-31 NA NA
#1970-02-01 NA NA
#1970-02-02  5  9
#1970-02-03  7 11
#1970-02-04  9 13
#1970-02-05 11 15
#1970-02-06 13 17
#1970-02-07 15 19
#1970-02-08 17 21

希望有帮助。