【发布时间】:2015-09-07 07:36:44
【问题描述】:
我正在尝试解决 data.table 中的一个问题,该问题需要我在下一步的预测中使用刚刚预测的值。
我有这样的数据设置,生成的 NA 行已准备好接收预测。每个 NA 是通过将其前面的值乘以当前参数来计算的
library(data.table)
dt <- data.table(
date = as.Date(paste(rep(c(2015, 2016), each = 12, times = 2), 1:12, 1, sep = "-")),
val = c(rnorm(12, 50, 5), rep(NA, 12)),
param1 = runif(48),
cat = rep(c("a", "b"), each = 24)
)
我不能这样做
dt[, {
dt_in <- .SD
lapply(dt_in[year(date) > 2015, date], function(d){
dt_sub <- dt_in[date <= d]
pred <- dt_sub[.N-1, val] * dt_sub[.N, param1]
dt_in[date == d, val := pred]
})
} , by = cat]
在尝试更新 {} 中的 .SD 时,给我“.SD 已锁定...”错误。我目前的解决方案包括将 data.table 分解为一个列表并逐行更新每个列表项
# Create a list of data.tables, one for each category
break_list <- lapply(dt[, unique(cat)], function(c){
dt[cat == c]
})
l_out <- lapply(break_list, function(dt_in){
# Select the dates requiring prediction
lapply(dt_in[year(date) > 2015, date], function(d){
# Subset by date
dt_sub <- dt_in[date <= d]
# Prediciton = value from the second to last row * parameter in the last row
pred <- dt_sub[.N-1, val] * dt_sub[.N, param1]
# Update data.table
dt_in[date == d, val := pred]
})
dt_in
})
dt_out <- rbindlist(l_out)
这可行,并为我提供了所需的解决方案,但它可能会很慢并且感觉就像我已经违反了所有 data.table 规则。有没有更好的办法?
【问题讨论】:
-
这是相当多的代码(这很好),但很少解释您要完成的工作。您能否向我们展示所需的结果应该是什么样的(并附上解释)。
-
Richard,在“dt”中,您将看到需要用预测替换的 NA。在 dt_out 中,您将找到所需的结果。大卫,我更新了更多信息。
-
@DavidArenburg 不正确 - 需要使用
dt_in <- copy(.SD)(data.table 通过引用复制 - 如果 a 被锁定 b -
@YAK dt_in
-
是的。它制作副本。除此之外,该解决方案几乎不可读……在我看来,仅当调用是独立的时才应使用 apply - 否则会非常混乱。我仍然觉得这个问题需要一些工作......使用像“计算”、“依赖”或“迭代”这样的词会使它更普遍并突出核心问题。如果您付出更多努力,我会尝试使用
data.table::set给出答案
标签: r data.table