如何在R的data.table包中用set函数按分组创建滞后变量
R data.table按分组批量生成滞后变量方案
set()函数本身没有内置分组参数,没办法直接在set的入参里指定分组规则,但是可以结合data.table的分组计算能力,拿到按id分组生成的滞后值后再通过set赋值,也可以直接用更简洁的data.table分组动态赋值语法实现需求,不需要嵌套循环,性能更高。
注意前提
在计算分组滞后前,必须先确保数据已经按分组内的排序规则完成排序(比如你有时间列的话,需要先按id + 时间列升序排序),否则滞后计算的顺序不符合预期。可以用setorder()完成排序:
# 示例:如果有时间列date就用setorder(DT, id, date),这里假设按现有行顺序为组内顺序 setorder(DT, id)
方案1:基于原有循环逻辑修改
只需要把set函数的value参数替换为按id分组计算的滞后结果即可:
ALL_FEATURES="index" LAG_VALS=1:2 for(each_var in ALL_FEATURES){ for(each_lag in LAG_VALS){ set(DT, j = paste0(each_var,"_lag_",each_lag), # 此处不需要eval,直接传字符串即可 value = DT[, shift(get(each_var), n = each_lag, type = "lag"), by = id]$V1 ) } }
方案2:更高效的无循环批量赋值(推荐)
直接用data.table的:=动态赋值语法,一次性生成所有分组滞后变量,不需要嵌套循环,代码更简洁,大样本下性能也更好:
ALL_FEATURES="index" LAG_VALS=1:2 # 批量生成所有滞后列名 lag_cols <- paste0(rep(ALL_FEATURES, each = length(LAG_VALS)), "_lag_", rep(LAG_VALS, length(ALL_FEATURES))) # 按id分组批量生成滞后变量 DT[, (lag_cols) := lapply(LAG_VALS, function(l) shift(.SD, n = l, type = "lag")), by = id, .SDcols = ALL_FEATURES]
核心逻辑说明:
.SDcols = ALL_FEATURES指定要计算滞后的变量范围by = id指定按id分组计算,每组内独立生成滞后项lapply(LAG_VALS, ...)遍历所有滞后阶数,对每个阶数给指定变量计算组内滞后(lag_cols) :=把计算结果赋值给提前生成好的对应列名
内容的提问来源于stack exchange,提问作者Abraham Mathew
相关产品推荐
相关产品推荐

