基于数据表的月度折现因子线性插值实现需求
对data.table中DF列执行分段线性插值生成月度折现因子
需求说明
需要将DT中DF列的0值替换为加权插值结果,分三段处理:
- 前11条记录(行1-11):基于初始值1(行1的DF)和第12条的0.98做线性插值
- 第13至23条记录:基于第12条的0.98和第23条的0.95做线性插值
- 最后两条记录(行25-26):直接使用0.95
原始数据
library(data.table) DT <- data.table(MM=c(1,2,3,4,5,6,7,8,9,10,11,12,12,14,15,16,17,18,19,20,21,22,23,24,25,26), DF=c(1,0,0,0,0,0,0,0,0,0,0,0.98,0,0,0,0,0,0,0,0,0,0,0.95,0,0,0))
按行号实现分段插值
使用data.table的fcase函数按行号匹配分段逻辑,结合线性插值公式计算:
# 添加行号列用于分段 DT[, row_num := .I] # 计算插值后的折现因子 DT[, DF_interpolated := fcase( # 保留行1的初始值1 row_num == 1, DF, # 行2-11:在1(行1)和0.98(行12)之间线性插值 row_num %between% c(2, 11), 1 + (0.98 - 1) * (row_num - 1) / (12 - 1), # 保留行12的0.98 row_num == 12, DF, # 行13-22:在0.98(行12)和0.95(行23)之间线性插值 row_num %between% c(13, 22), 0.98 + (0.95 - 0.98) * (row_num - 12) / (23 - 12), # 保留行23的0.95 row_num == 23, DF, # 行24-26:直接赋值0.95(若仅需最后两条,可改为row_num %between% c(25,26)) row_num >= 24, 0.95 )] # 查看结果 DT[, .(row_num, MM, DF, DF_interpolated)]
线性插值公式说明
对于两个已知点(位置pos0,值val0)和(位置pos1,值val1),任意位置pos的插值结果为:
插值值 = val0 + (val1 - val0) * (pos - pos0) / (pos1 - pos0)
该公式保证插值结果在两点间呈线性变化,符合月度折现因子的平滑过渡需求。
按月份(MM)插值(可选)
若希望按MM(月份)而非行号插值(适配月度逻辑),可调整逻辑如下:
DT[, DF_interpolated_by_MM := fcase( # MM1-11:在MM1(DF=1)和MM12(DF=0.98)之间插值 MM <= 11, 1 + (0.98 - 1) * (MM - 1) / (12 - 1), # MM13-22:在MM12(DF=0.98)和MM23(DF=0.95)之间插值 MM >=13 & MM <=22, 0.98 + (0.95 - 0.98) * (MM - 12) / (23 - 12), # MM24-26:直接用0.95 MM >=24, 0.95, # 保留原有非0值 default = DF )]
内容的提问来源于stack exchange,提问作者highbury
相关产品推荐
相关产品推荐

