我在使用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"]
我无法弄清楚zoo
函数和roll
函数有什么不同。它们各自返回数字向量。任何指导意见。
答案 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}}