使用预测值在 data.table 中进行预测
Using predicted values to make predictions in data.table
我正在尝试解决 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 规则。有没有更好的方法?
您正在寻找迭代更新 data.table 的行,其中的值是根据上一次迭代中更新的行计算得出的。虽然通常最好找到使更新独立的问题的明确表述,并且在您的情况下可以使用包含 param1
的 cumprod
的辅助列和滚动连接(dt[dt[...], ..., roll=TRUE]
) 我将展示如何使用 data.table::set
有效地对 data.table 进行迭代更新,因为前者并不总是 easy/possible:
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
在您的情况下)作为变量名(即使在不同的命名空间中)通常不是一个好主意。
我正在尝试解决 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 规则。有没有更好的方法?
您正在寻找迭代更新 data.table 的行,其中的值是根据上一次迭代中更新的行计算得出的。虽然通常最好找到使更新独立的问题的明确表述,并且在您的情况下可以使用包含 param1
的 cumprod
的辅助列和滚动连接(dt[dt[...], ..., roll=TRUE]
) 我将展示如何使用 data.table::set
有效地对 data.table 进行迭代更新,因为前者并不总是 easy/possible:
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
在您的情况下)作为变量名(即使在不同的命名空间中)通常不是一个好主意。