在SAS EG中按ID合并含多日期列的多行数据
合并同一ID的多行数据,填充所有日期列
我有一张包含ID列与多个DATE列的表,每当ID对应的某日期列有数据时,该ID的行就会重复出现。我希望将这些行合并为每个ID仅一行,同时填充所有日期列的数据。已尝试对数据进行转置、排序,再通过PROC SQL按ID_COLUMN分组处理,但未得到理想结果。
当前输出示例
| ID | DATE1 | DATE2 | DATE3 |
|---|---|---|---|
| 101 | 2023-01-01 | . | . |
| 101 | . | 2023-02-15 | . |
| 101 | . | . | 2023-03-20 |
| 102 | 2023-04-05 | . | . |
| 102 | . | 2023-05-10 | . |
期望输出示例
| ID | DATE1 | DATE2 | DATE3 |
|---|---|---|---|
| 101 | 2023-01-01 | 2023-02-15 | 2023-03-20 |
| 102 | 2023-04-05 | 2023-05-10 | . |
解决方案
方法1:PROC SQL 聚合函数法
直接通过分组+MAX()函数提取每个ID的非缺失日期值,MAX()会自动忽略缺失值(.):
PROC SQL; CREATE TABLE merged_data AS SELECT ID_COLUMN, MAX(DATE1) AS DATE1 FORMAT=YYMMDD10., MAX(DATE2) AS DATE2 FORMAT=YYMMDD10., MAX(DATE3) AS DATE3 FORMAT=YYMMDD10. /* 按实际日期列数量依次添加后续列 */ FROM original_data GROUP BY ID_COLUMN; QUIT;
注意:如果日期列存储为字符型,改用MAXC()函数替代MAX()。
方法2:DATA步+RETAIN+数组法
适合日期列较多的场景,无需逐个列编写逻辑:
/* 先按ID排序,确保同一ID的行连续 */ PROC SORT DATA=original_data; BY ID_COLUMN; RUN; DATA merged_data; SET original_data; BY ID_COLUMN; /* 定义数组覆盖所有日期列 */ ARRAY dates[*] DATE1-DATE3; /* 可替换为实际列名列表,如 DATE1 DATE5 DATE7 */ ARRAY _temp_dates[*] _TEMP_DATE1-_TEMP_DATE3; /* 临时数组存储保留值 */ /* 保留临时数组的值,跨行不重置 */ RETAIN _TEMP_DATE1-_TEMP_DATE3; /* 用当前行的非缺失值更新临时数组 */ DO i = 1 TO DIM(dates); IF NOT MISSING(dates[i]) THEN _temp_dates[i] = dates[i]; END; /* 将临时数组的值赋值回原日期列 */ DO i = 1 TO DIM(dates); dates[i] = _temp_dates[i]; END; /* 仅输出同一ID的最后一行 */ IF LAST.ID_COLUMN THEN OUTPUT; /* 清理临时变量 */ DROP i _TEMP_DATE1-_TEMP_DATE3; RUN;
内容的提问来源于stack exchange,提问作者cole_a
相关产品推荐
相关产品推荐

