R data.table按数据点数量限制窗口的滚动连接问题
按数据点行数限制data.table滚动连接的方法
问题场景
现有如下data.table数据:
dates = as.Date(c('2000-01-01','2000-02-01','2000-03-01','2000-04-01')) dt = data.table(date = dates[1:2], value = c(1,2))
查看原始数据:
> dt date value <Date> <num> 1: 2000-01-01 1 2: 2000-02-01 2
当用所有日期做全连接时,缺失的value显示为NA:
> dt[J(dates), on = 'date'] date value <Date> <num> 1: 2000-01-01 1 2: 2000-02-01 2 3: 2000-03-01 NA 4: 2000-04-01 NA
需求是将value向前滚动,但仅限制滚动1个数据点(即只填充下一个缺失行2000-03-01的value,2000-04-01保持NA)。而默认的roll参数是按连接列(date)的单位(天数)设置限制,比如roll=30能得到目标结果,但如果日期间隔不固定,这种方法就不适用。
解决方案
方法一:基于行号的滚动连接
通过给数据表添加行号,用行号作为连接键,严格限制滚动行数:
# 为原始数据添加行号 dt[, rn := .I] # 创建包含所有日期和对应行号的查询表 query_dt = data.table(date = dates, rn = seq_along(dates)) # 按行号连接,roll=1表示仅允许行号差≤1的滚动 result = query_dt[dt, on = 'rn', roll = 1][, .(date, value)] # 按日期排序确保顺序正确 setorder(result, date)
运行结果:
> result date value <Date> <num> 1: 2000-01-01 1 2: 2000-02-01 2 3: 2000-03-01 2 4: 2000-04-01 NA
这种方法不依赖日期间隔,无论日期是每天、每周还是不规则间隔,都只会向前滚动1个数据点。
方法二:全连接后条件填充
先完成全连接,再通过判断相邻行的NA状态来填充:
# 全连接所有日期 full_dt = dt[J(dates), on = 'date'] # 仅填充前一行有非NA值的缺失行 full_dt[, value := fifelse(is.na(value) & shift(!is.na(value), fill = FALSE), shift(value), value)]
运行结果与方法一一致:
> full_dt date value <Date> <num> 1: 2000-01-01 1 2: 2000-02-01 2 3: 2000-03-01 2 4: 2000-04-01 NA
这种方法更简洁,适合不需要复杂连接逻辑的场景。
内容的提问来源于stack exchange,提问作者jf328
相关产品推荐
相关产品推荐

