使用带有data.table的滚动功能

时间:2018-03-06 19:13:54

标签: r data.table vectorization

我在使用roll专门应用data.table包中的函数时遇到问题。我正在尝试为每个组DT$obs计算列DT$group上的滚动指标。我能够使用zoo包计算滚动指标,但我想在roll包函数中使用一些其他参数。

错误演示如下。

require(data.table)
require(zoo)
require(roll)


# Fabricated Data:
DT <- data.table(group = rep(c("A", "B"), each = 20), obs = runif(40, min = 0, max = 100))


# Calculate a rolling sum (this is working properly)
DT[, RollingSum := lapply(.SD, function(x) zoo::rollsumr(x, k = 5, fill = NA)), by = "group", .SDcols = "obs"]


# Attempt to calculate a rolling z-score (this throws me an error)
DT[, RollingZScore := lapply(.SD, function(x) roll::roll_scale(as.matrix(x), width = 10, min_obs = 5)), by = "group", .SDcols = "obs"]

enter image description here

我无法弄清楚zoo函数和roll函数有什么不同。它们各自返回数字向量。任何指导意见。

2 个答案:

答案 0 :(得分:2)

正如@Frank所描述的那样,问题是roll_scale(以及lapply输出的每个元素)的结果是一个矩阵。您可以使用sapply代替lapply,也可以将as.vector放在函数定义中。

DT[, RollingZScore := sapply(.SD, 
                             function(x) roll::roll_scale(as.matrix(x), width = 10, min_obs = 5)), 
   by = "group", .SDcols = "obs"]

DT[, RollingZScore := lapply(.SD, 
                              function(x) as.vector(roll::roll_scale(as.matrix(x), width = 10, min_obs = 5))), 
    by = "group", .SDcols = "obs"]

答案 1 :(得分:1)

如果输入的元素少于5个,只需定义一个返回NA的函数,就可以使用Scale <- function(x) if (length(x) < 5) NA else tail(scale(x), 1) DT[, rollingScore := rollapplyr(obs, 10, Scale, partial = TRUE), by = "group"] 完成此操作:

{{1}}