如何在SAS中实现透视表列堆叠?附示例数据与尝试记录
SAS数据透视解决方案:按Name分组、Date+车辆类型为列的数据集生成
原始数据
Name Date Car Bus Taxi Auto Adam 9_2023 15 0 -30 85 Adam 10_2024 25 -26 27 0 Adam 11_2025 0 10 15 0 Luke 8_2023 -5 5 67 20 Luke 9_2023 30 -45 0 0 Luke 10_2024 20 0 90 -15 Luke 11_2025 0 0 0 0
需求说明
需要将上述数据转换为Name为行维度,Date与Car/Bus/Taxi/Auto的组合为列维度的透视表数据集,期望输出格式如下:
Car Bus Taxi Auto Name 8_2023 9_2023 10_2023 11_2023 8_2023 9_2023 10_2023 11_2023 8_2023 9_2023 10_2023 11_2023 8_2023 9_2023 10_2023 11_2023 Adam 0 15 25 0 0 0 -26 10 0 -30 27 15 0 85 0 0 Luke -5 30 20 0 5 -45 0 0 67 0 90 0 20 0 -15 0
已尝试代码及问题
- 未指定Name为行维度的PROC TABULATE:
proc tabulate data = test out=output; class Name Date; var Car Bus Taxi Auto; tables Car*Date Bus*Date Taxi*Date Auto*Date; run;
问题:输出为按Date汇总的结果,未按Name拆分,不符合需求:
Date _TYPE_ _PAGE_ _TABLE_ Car_Sum Bus_Sum Taxi_Sum Auto_Sum 8_2023 1 1 1 -5 5 67 20 9_2023 1 1 1 45 -45 -30 85 10_2023 1 1 1 45 -26 117 -15 11_2023 1 1 1 0 10 15 0
- 使用BY Name的PROC TABULATE:
proc tabulate data = test out=output; by Name; class Date; var Car Bus Taxi Auto; tables Car*Date Bus*Date Taxi*Date Auto*Date; run;
问题:结果报表格式符合要求,但每个Name对应单独表格,无法生成统一的数据集用于后续关联操作。
解决方案
方法一:使用PROC TABULATE生成统一数据集
修正PROC TABULATE语法,将Name作为行维度,同时指定输出数据集并清理冗余变量,缺失值自动填充为0:
proc tabulate data=test out=final_output(drop=_TYPE_ _PAGE_ _TABLE_); class Name Date; var Car Bus Taxi Auto; /* 设置Name为行,车辆类型*日期为列,计算Sum并隐藏列标题后缀 */ tables Name, (Car*Date Bus*Date Taxi*Date Auto*Date)*Sum=''; /* 将缺失值替换为0 */ format _numeric_ 8.; run; /* 若需确保缺失值为0,可追加数据步处理 */ data final_output; set final_output; array cols _numeric_; do over cols; if cols = . then cols = 0; end; run;
方法二:使用PROC TRANSPOSE转置实现
通过两次转置,先将宽表转成长表,再生成复合列名的宽表:
/* 第一步:将原始宽表转成长表,拆分车辆类型和对应数值 */ proc transpose data=test out=test_long(rename=(col1=Value _NAME_=Type)); by Name Date; var Car Bus Taxi Auto; run; /* 第二步:按Name分组,以Type+Date为列名转成宽表 */ proc transpose data=test_long out=test_wide(drop=_NAME_) prefix=; by Name; id Type Date; var Value; run; /* 第三步:将缺失值替换为0,匹配期望输出 */ data final_output; set test_wide; array all_nums _numeric_; do over all_nums; if all_nums = . then all_nums = 0; end; run;
两种方法生成的final_output数据集均可直接用于后续关联操作,列名格式为Car_8_2023、Bus_9_2023等,与期望的表头结构对应。
内容的提问来源于stack exchange,提问作者Fanatic
相关产品推荐
相关产品推荐

