求助:SAS中宽表转长表并生成年度服务统计结果的实现
修正方案
原代码问题说明
- PROC SQL中的
distinct完全多余——sum()聚合函数对每个字段计算后只会返回一行结果,加distinct不会改变输出,反而容易混淆逻辑。 - 转置后未完成字段映射:默认生成的
_NAME_列存储原变量名(如kl2_2016),COL1列存储对应年份的总和,没有提取纯年份值,也未将总和列重命名为目标的total_service。
方法一:基于原有代码的修正
保留你的核心逻辑,补充字段处理步骤:
/* 第一步:计算各年份参与人数总和,移除多余的distinct */ proc sql; create table year_service as select sum(kl2_2016) as kl2_2016, sum(kl2_2017) as kl2_2017, sum(kl2_2018) as kl2_2018, sum(kl2_2019) as kl2_2019, sum(kl2_2020) as kl2_2020, sum(kl2_2021) as kl2_2021, sum(kl2_2022) as kl2_2022, sum(kl2_2023) as kl2_2023, sum(kl2_2024) as kl2_2024, sum(kl2_2025) as kl2_2025 from have; quit; /* 第二步:转置并重命名总和列 */ proc transpose data=year_service out=year_service_long(rename=(COL1=total_service)) name=var_name; var kl2_2016-kl2_2025; run; /* 第三步:从变量名中提取年份,生成目标结构 */ data year_service_final; set year_service_long; /* 截取变量名中第4位开始的4个字符,转换为数值型年份 */ year = input(substr(var_name,4,4),4.); /* 只保留需要的字段 */ keep year total_service; run;
方法二:更灵活的高效写法(推荐)
先将宽表转成个体-年份的长表,再按年份聚合求和,新增年份时无需修改代码:
/* 第一步:把宽表转成每个ID对应各年份的参与状态长表 */ proc transpose data=have out=have_long(rename=(COL1=participate)) name=var_name; by ID; var kl2_2016-kl2_2025; run; /* 第二步:提取年份并计算年度总人数 */ proc sql; create table year_service_final as select input(substr(var_name,4,4),4.) as year, sum(participate) as total_service from have_long group by calculated year order by year; quit;
如果想一步完成,也可以用PROC SUMMARY简化:
proc summary data=have nway; var kl2_2016-kl2_2025; output out=year_service sum=; run; proc transpose data=year_service(where=(_TYPE_=0)) out=year_service_final(rename=(COL1=total_service)); var kl2_2016-kl2_2025; run; data year_service_final; set year_service_final; year = input(substr(_NAME_,4,4),4.); keep year total_service; run;
内容的提问来源于stack exchange,提问作者Kelly
相关产品推荐
相关产品推荐

