SAS中如何快速填补日期序列缺失值并沿用前交易日数据?
SAS高效补全非交易日数据并沿用前值的方法
针对股票/债券交易日数据补全周末、节假日日期,并将缺失日期的数值沿用前一个交易日数据的需求,以下是两种比传统DO循环+RETAIN更高效的实现方式:
方法1:PROC EXPAND(ETS模块,推荐)
SAS的ETS模块中PROC EXPAND专门用于时间序列的扩展与插值,一步即可完成日期补全+前向填充(LOCF),无需手动生成日期序列:
示例代码
/* 模拟仅含交易日的原始数据 */ data have; input date :yymmdd10. price; format date yymmdd10.; datalines; 2022-06-30 98 2022-07-01 100 2022-07-05 102 ; run; /* 补全日期并沿用前值 */ proc expand data=have out=want method=none; id date interval=day; /* 指定时间间隔为天,自动补全所有连续日期 */ convert price / transformout=(locf); /* LOCF=前一个非缺失值填充 */ run;
关键参数说明
method=none:仅扩展时间点,不做插值计算transformout=(locf):对缺失的price字段使用最后一次观测值填充,完全匹配需求- 若需排除自定义节假日,可添加
holiday=节假日数据集参数(需提前定义节假日的日期变量)
方法2:无ETS模块时的替代方案
如果没有ETS模块权限,可通过PROC SQL生成完整日期序列,再结合DATA步的RETAIN逻辑实现,效率远高于手动DO循环:
示例代码
/* 第一步:生成原始数据的完整日期范围 */ proc sql noprint; /* 获取原始数据的首尾日期 */ select min(date), max(date) into :start_dt, :end_dt from have; /* 生成从首到尾的所有日期(SAS 9.4M5+支持GENERATE函数) */ create table full_dates as select intnx('day', &start_dt, i) as date format=yymmdd10. from generate(0, intck('day', &start_dt, &end_dt)); quit; /* 第二步:合并原始数据并填充前值 */ data want; merge full_dates have; by date; retain last_valid_price; /* 更新有效价格,缺失时沿用前值 */ if not missing(price) then last_valid_price = price; else price = last_valid_price; drop last_valid_price; run;
优势说明
- 用
GENERATE函数生成日期序列,比DO循环更高效(底层为向量运算) - 合并逻辑简洁,RETAIN仅保存有效价格,避免冗余计算
内容的提问来源于stack exchange,提问作者Stacked_sas
相关产品推荐
相关产品推荐

