如何仅对每个ID下重复日期对应的变量值求和?
SAS中按ID+日期分组求和的实现方案
需求说明
对每个ID下的重复日期对应的Value字段求和,唯一日期保留原Value值,最终每个ID+Date组合只保留一条记录,Value为该组合下所有值的总和。
输入数据集
data have; input ID :$20. Date :date09. Value; format Date date9. Value; cards; 0001 13JAN2017 0 0001 22FEB2017 1 0001 22FEB2017 1 0001 30JAN2019 0 0002 28DEC2014 1 0002 28DEC2014 2 0002 28DEC2014 1 0002 28DEC2014 0 0003 15DEC2021 0 0003 16DEC2021 1 ; run;
期望输出数据集
data want; input ID :$20. Date :date09. Value; format Date date9. Value; cards; 0001 13JAN2017 0 0001 22FEB2017 2 0001 30JAN2019 0 0002 28DEC2014 4 0003 15DEC2021 0 0003 16DEC2021 1 ; run;
解决方案
方法1:使用PROC SUMMARY(简洁高效)
这是SAS处理分组聚合最常用的方法,无需手动排序,代码简洁:
proc summary data=have nway; class ID Date; var Value; output out=want_sum(drop=_type_ _freq_) sum=Value; run; /* 恢复日期格式,避免PROC SUMMARY自动丢失格式 */ proc datasets lib=work nolist; modify want_sum; format Date date9.; run; quit;
nway参数:仅保留ID+Date的最高维度分组结果,不会生成其他层级的聚合数据output语句:指定求和后的字段名为Value,同时删除系统自动生成的_type_(分组类型标记)和_freq_(分组记录数)字段- 最后通过
proc datasets恢复日期格式,保证输出的日期显示符合要求
方法2:使用DATA步(自定义逻辑灵活)
如果需要更灵活的自定义处理逻辑,可以用DATA步实现,前提是先对数据集排序:
/* 先按ID和Date排序,确保同组记录连续 */ proc sort data=have; by ID Date; run; data want_data; set have; by ID Date; retain Total 0; /* 让Total变量在循环中保留上一次的值,实现累加 */ Total + Value; /* 累加当前记录的Value到Total */ /* 当遇到当前Date组的最后一条记录时,输出结果 */ if last.Date then do; Value = Total; /* 把累加结果赋值给Value */ output; Total = 0; /* 重置Total,准备处理下一个分组 */ end; run;
by ID Date:按ID和Date分组,系统自动生成first.Date和last.Date两个标记变量retain Total 0:确保Total变量不会在每次循环时被重置为缺失值last.Date:判断是否为当前Date组的最后一条记录,此时输出累加后的结果
内容的提问来源于stack exchange,提问作者NewUsr_stat
相关产品推荐
相关产品推荐

