data.table中按行内容条件执行na.locf缺失值向前填充
R data.table 按列条件执行缺失值末次向前填充方案
需求说明
使用data.table处理数据时实现条件na.locf(Last Observation Carried Forward,末次观测向前填充):
- 仅当某一列的第二行取值包含
Coupon时,才对该列的缺失值执行向前填充 - 其余列不做任何填充处理
原始样例数据
dt <- as.data.table(structure(list(V1 = c("Bond 1", "Yield", NA, NA, "3", "4", "5" ), V2 = c("Bond 1", "Coupon", "0.11", NA, NA, NA, NA), V3 = c("Bond 1", "Rating", "A", NA, NA, NA, NA), V4 = c("Bond 2", "Yield", "1", "2", "3", "4", "5"), V5 = c("Bond 2", "Coupon", "0.25", NA, NA, NA, NA), V6 = c("Bond 2", "Rating", "AA", NA, NA, NA, NA)), class = "data.frame", row.names = c(NA, -7L)))
原始数据打印效果:
V1 V2 V3 V4 V5 V6 1: Bond 1 Bond 1 Bond 1 Bond 2 Bond 2 Bond 2 2: Yield Coupon Rating Yield Coupon Rating 3: <NA> 0.11 A 1 0.25 AA 4: <NA> <NA> <NA> 2 <NA> <NA> 5: 3 <NA> <NA> 3 <NA> <NA> 6: 4 <NA> <NA> 4 <NA> <NA> 7: 5 <NA> <NA> 5 <NA> <NA>
期望输出效果
V1 V2 V3 V4 V5 V6 1: Bond 1 Bond 1 Bond 1 Bond 2 Bond 2 Bond 2 2: Yield Coupon Rating Yield Coupon Rating 3: <NA> 0.11 A 1 0.25 AA 4: <NA> 0.11 <NA> 2 0.25 <NA> 5: 3 0.11 <NA> 3 0.25 <NA> 6: 4 0.11 <NA> 4 0.25 <NA> 7: 5 0.11 <NA> 5 0.25 <NA>
可运行实现代码
方案1:依赖zoo包的na.locf
library(data.table) library(zoo) # 筛选第二行取值包含Coupon的目标列 target_cols <- names(dt)[as.character(dt[2,]) %like% "Coupon"] # 仅对目标列执行locf填充 dt[, (target_cols) := lapply(.SD, na.locf, na.rm = FALSE), .SDcols = target_cols]
方案2:无额外依赖,用data.table原生函数(性能更优)
不需要加载zoo包,直接用data.table自带的nafill函数实现locf逻辑:
library(data.table) target_cols <- names(dt)[as.character(dt[2,]) %like% "Coupon"] dt[, (target_cols) := lapply(.SD, nafill, type = "locf"), .SDcols = target_cols]
原错误代码问题说明
之前尝试的代码dt[, if(dt[2,]=="TR.ADF_COUPON") na.locf]无法运行,原因如下:
- 不符合data.table语法规范:j位置的if判断无法自动按列循环处理,也没有通过
:=运算符完成列更新 - 匹配值错误:代码里判断的目标值是
TR.ADF_COUPON,和实际需求里的Coupon不匹配 - 没有指定处理范围:没有通过
.SDcols明确需要执行填充的列,会导致所有列被错误处理
内容的提问来源于stack exchange,提问作者Elias K.
相关产品推荐
相关产品推荐

