如何用Proc Report或Data Step实现分组变量的多列计数表格?
用Proc Report或Data Step实现分组多列计数
完全可以用Proc Report或更简洁的Data Step工作流替代多次SQL分组再连接的繁琐操作,以下是两种可行方案的示例:
先构造示例数据集
先准备一份模拟业务数据,方便你直接运行测试:
data have; input Department $ Building_code $; datalines; HR A HR A HR B Finance B Finance C IT A IT A IT B IT C IT C ; run;
方案一:直接用Proc Report实现
通过Proc Report的compute块,在分组过程中直接完成不同Building的条件计数,无需额外预处理:
proc report data=have nowindows headline headskip; columns Department Count_A Count_B Count_C; define Department / group '部门'; define Count_A / computed 'Building A 数量'; define Count_B / computed 'Building B 数量'; define Count_C / computed 'Building C 数量'; /* 分组前初始化计数变量 */ compute before Department; count_a = 0; count_b = 0; count_c = 0; endcomp; /* 逐行判断并累加对应Building的计数 */ compute; if Building_code = 'A' then count_a + 1; else if Building_code = 'B' then count_b + 1; else if Building_code = 'C' then count_c + 1; endcomp; /* 分组结束后输出汇总结果 */ compute after Department; line @1 Department $10. count_a 5. count_b 5. count_c 5.; count_a = 0; count_b = 0; count_c = 0; endcomp; /* 跳过原始数据行,只保留分组汇总行 */ break after Department / skip; run;
方案二:Data Step分组计数 + Proc Transpose转置
如果你的Building_code取值较多且可能新增,这种方式更灵活,无需手动维护每个列的逻辑:
/* 第一步:按部门和Building分组统计数量 */ data count_temp; set have; by Department Building_code; if first.Building_code then count = 0; count + 1; if last.Building_code then output; /* 只输出每组最后一行的累计值 */ run; /* 第二步:转置为宽表,自动生成各Building对应的计数列 */ proc transpose data=count_temp out=want prefix=Count_; by Department; id Building_code; /* 用Building_code的值作为列名前缀 */ var count; run; /* 可选:用Proc Report格式化展示结果 */ proc report data=want nowindows headline headskip; columns Department Count_A Count_B Count_C; define Department / group '部门'; define Count_A / display 'Building A 数量'; define Count_B / display 'Building B 数量'; define Count_C / display 'Building C 数量'; run;
这两种方案都比多次SQL分组再连接高效,新增Building_code时:
- 方案一只需新增对应的
Count_X列定义和compute块中的判断逻辑; - 方案二更省心,无需修改代码,转置会自动识别新的Building_code并生成对应列。
内容的提问来源于stack exchange,提问作者Kristián Ővári
相关产品推荐
相关产品推荐

