data.table分组调用lapply时如何处理j位置的data.frame输出完成列赋值
data.table批量赋值BBands返回多列的解决方法
报错的核心原因是
BBands()返回的是4列的矩阵对象,你直接用lapply遍历窗口大小后返回的是「每个窗口对应1个4列矩阵」的嵌套结构,不符合data.table的:=赋值要求的「每个元素对应1个单列向量」的规则。
解决方案1(匹配你提前生成的new_cols,改动最小)
直接把原代码里的赋值行替换为以下内容即可运行:
output_bbands <- dt[, (new_cols) := do.call(c, lapply(window_sizes, function(w) { # 把BBands返回的矩阵拆为4个独立向量组成的列表 as.list(as.data.table(BBands(Close, n = w))) })), by = symbol]
实现逻辑:
as.list(as.data.table(BBands(...)))会把每个窗口返回的4列矩阵,拆成4个长度等于分组行数的向量,组成长度为4的列表do.call(c, ...)会把所有窗口对应的列表拼接为总长度为8的列表(2个窗口*4列),和你提前生成的new_cols的数量、顺序完全匹配:=按顺序把列表里的每个向量赋值给对应的新列
解决方案2(自动生成列名,避免顺序错误)
如果不想提前手动生成列名,可以用以下写法,自动生成符合命名规则的新列:
output_bbands <- dt[, { bbands_list <- lapply(window_sizes, function(w) { bbands_dt <- as.data.table(BBands(Close, n = w)) # 按规则自动重命名列 setnames(bbands_dt, paste0("bbands_", names(bbands_dt), "_", w)) bbands_dt }) # 拼接所有指标列后自动赋值到原表 do.call(cbind, bbands_list) }, by = symbol]
运行后可以用head(dt[, new_cols, with = FALSE])验证新列是否正常生成。
内容的提问来源于stack exchange,提问作者Mislav Sagovac
相关产品推荐
相关产品推荐

