SAS缺失日期补全:为行业-起始年组补全缺失月份行
问题描述
数据集示例
| 行业(industry) | 起始年份(start_year) | 首次日期(first_date) | no1 | no2 | ... |
|---|---|---|---|---|---|
| A | 1990 | 200201 | 5 | 15 | |
| A | 1990 | 200202 | 5 | 15 | |
| A | 1990 | 200204 | 5 | 15 | |
| A | 1990 | 200205 | 5 | 15 |
数据集说明
- 包含多个行业(A、B、C、D等),每个行业对应多个起始年份(如1990、1991等),不同行业的起始年份可能不同(例如X行业起始于1990年,Y行业起始于2005年)
first_date为数值型字段,格式为YYYYMM(如200201代表2002年1月)no1、no2及其他数值列无业务关联
需求
补全每个行业-起始年份分组下的所有月份日期,例如示例中缺失200203,需新增一行:行业为A、起始年份1990、first_date为200203,其余数值列填充0。
已完成操作
/* 生成所有存在的组合 */ PROC SQL; CREATE TABLE all_combinations AS SELECT DISTINCT Branche, Anfangsjahr, Erstes Datum FROM have; QUIT; /* 提取年份和月份 */ DATA all_combinations_year_month; SET all_combinations; jahr = int(Erstes Datum / 100); monat = mod(Erstes Datum, 100); /* 使用mdy函数转换为SAS日期 */ sasDatum = mdy(monat, 1, jahr); format sasDatum date9.; /* 设置日期格式 */ run;
已成功将数值型日期转换为SAS日期,但不清楚后续如何实现补全缺失月份行的需求。
解决方案
步骤1:确定每个分组的日期范围
先获取每个行业-起始年份分组下的最小和最大sasDatum,明确需要补全的月份区间:
PROC SQL; CREATE TABLE group_dates AS SELECT Branche, Anfangsjahr, MIN(sasDatum) AS min_sasdate FORMAT=date9., MAX(sasDatum) AS max_sasdate FORMAT=date9. FROM all_combinations_year_month GROUP BY Branche, Anfangsjahr; QUIT;
步骤2:生成每个分组的完整月份序列
利用SAS的INTNX函数生成分组内从最小到最大日期的所有月份第一天,再转换回YYYYMM格式的数值型first_date:
DATA full_month_sequence; SET group_dates; /* 遍历生成该分组下的所有月份日期 */ DO sasDatum = min_sasdate TO max_sasdate BY INTNX('month', 0, 1); /* 将SAS日期转换为YYYYMM格式的数值 */ first_date = YEAR(sasDatum)*100 + MONTH(sasDatum); OUTPUT; END; FORMAT sasDatum date9.; DROP min_sasdate max_sasdate; RUN;
步骤3:关联原数据并填充缺失值
将完整月份序列与原数据集左关联,缺失的数值列用0填充:
PROC SQL; CREATE TABLE final_data AS SELECT f.Branche, f.Anfangsjahr, f.first_date, COALESCE(h.no1, 0) AS no1, COALESCE(h.no2, 0) AS no2, /* 其他数值列按此格式处理:COALESCE(h.列名, 0) AS 列名 */ COALESCE(h.其他列名, 0) AS 其他列名 FROM full_month_sequence f LEFT JOIN have h ON f.Branche = h.Branche AND f.Anfangsjahr = h.Anfangsjahr AND f.first_date = h.Erstes Datum ORDER BY f.Branche, f.Anfangsjahr, f.first_date; QUIT;
补充说明
- 若原数据中
Erstes Datum是带空格的字段名,建议先重命名为无空格名称(如first_date_raw),避免SQL关联时出现语法错误 - 若需要补全的是从起始年份全年开始的所有月份(而非仅现有数据的最小到最大日期),可修改
group_dates中的min_sasdate为MDY(1,1,Anfangsjahr)(即起始年份的1月1日)
内容的提问来源于stack exchange,提问作者lissy1234567
相关产品推荐
相关产品推荐

