我正在尝试在向下滑动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,如何实现匿名功能或两者。
答案 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
希望有帮助。