【问题标题】:Using predicted values to make predictions in data.table使用预测值在 data.table 中进行预测
【发布时间】: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 &lt;- copy(.SD) (data.table 通过引用复制 - 如果 a 被锁定 b
  • @YAK dt_in
  • 是的。它制作副本。除此之外,该解决方案几乎不可读……在我看来,仅当调用是独立的时才应使用 apply - 否则会非常混乱。我仍然觉得这个问题需要一些工作......使用像“计算”、“依赖”或“迭代”这样的词会使它更普遍并突出核心问题。如果您付出更多努力,我会尝试使用data.table::set 给出答案

标签: r data.table


【解决方案1】:

您希望使用从前一次迭代中更新的行计算的值迭代更新 data.table 的行。虽然通常最好找到使更新独立的问题的明确表述,并且在您的情况下,可以使用包含param1cumprod 和滚动连接(dt[dt[...], ..., roll=TRUE])的辅助列,我将展示如何使用data.table::set 有效地对 data.table 进行迭代更新,因为前者并不总是容易/可能的:

setkey(dt, cat, date) # sort by cat first then by date in have the reference value used for each calculation in the row above
val_col_nr <- which(colnames(dt)=="val") # set requires a column number
dt[is.na(val), # we want to compute new values for val where val currently is NA
   # .I is a vector the row numbers (in dt) of each row in .SD
   for (ii in .I) set(dt, i=ii, j=val_col_nr, value=dt[ii,param1]*dt[ii-1L,val]),
   by=cat] # for every 'cat'

您可以使用identical(dt, setkey(dt_out,cat,date))查看结果。

还请注意,使用基本函数的名称(在您的情况下为 cat)作为变量名称(即使在不同的命名空间中)通常是一个坏主意。

【讨论】:

  • 我忘记了 cat 是一个基本功能 - 感谢提醒
猜你喜欢
  • 1970-01-01
  • 2019-05-09
  • 2020-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-23
  • 2018-09-24
  • 2019-05-06
相关资源
最近更新 更多