如何在SAS中计算员工同类错误按月重复出现的次数
SAS 员工错误计数实现方案
样例数据说明
你提供的原始数据结构如下:
Employee_ID Error_Type Month Count ------------------------------------------- 101 A Jan'21 1 102 B Jan'21 1 103 C Jan'21 1 101 B Feb'21 1 102 B Feb'21 2 103 C Feb'21 2 101 A Mar'21 1 102 B Mar'21 3 103 A Mar'21 1 101 A Apr'21 2 102 B May'21 3 103 C May'21 2
实现逻辑
按如下步骤处理即可匹配计数规则:
- 把字符格式的月份(如
Jan'21)转换为SAS日期数值,方便计算月份间隔 - 按
Employee_ID、Error_Type、转换后的日期升序排序 - 对每个
(Employee_ID, Error_Type)分组遍历:- 维护两个变量:当前连续计数
current_cnt、历史最大连续计数max_cnt - 组内第一条记录:
current_cnt = 1,max_cnt = 1,输出Count = current_cnt - 后续记录:计算当前月份和上一条同组记录的月份差
- 若间隔为1个月(连续出现):
current_cnt + 1,更新max_cnt = max(max_cnt, current_cnt),输出Count = current_cnt - 若间隔大于1个月(中断后再次出现):
current_cnt = max_cnt,输出Count = current_cnt
- 若间隔为1个月(连续出现):
- 维护两个变量:当前连续计数
完整SAS代码
/* 1. 模拟导入原始输入数据集,命名为raw_data */ data raw_data; input Employee_ID Error_Type $ Month $ @@; datalines; 101 A Jan'21 102 B Jan'21 103 C Jan'21 101 B Feb'21 102 B Feb'21 103 C Feb'21 101 A Mar'21 102 B Mar'21 103 A Mar'21 101 A Apr'21 102 B May'21 103 C May'21 ; run; /* 2. 转换字符月份为SAS日期,方便排序和计算间隔 */ data prep_data; set raw_data; /* 去掉月份中的单引号后按monyyy5.格式解析 */ month_dt = input(tranwrd(Month, "'", ""), monyy5.); format month_dt monyy7.; run; /* 3. 按员工、错误类型、日期升序排序 */ proc sort data=prep_data; by Employee_ID Error_Type month_dt; run; /* 4. 分组计算Count值 */ data result; set prep_data; by Employee_ID Error_Type month_dt; retain current_cnt max_cnt; /* 新分组初始化变量 */ if first.Error_Type then do; current_cnt = 1; max_cnt = 1; end; else do; /* 计算和上一条同组记录的月份差 */ month_diff = intck('month', lag(month_dt), month_dt); if month_diff = 1 then do; current_cnt + 1; /* 更新历史最大连续计数 */ if current_cnt > max_cnt then max_cnt = current_cnt; end; else do; /* 中断后复现,沿用历史最大计数 */ current_cnt = max_cnt; end; end; Count = current_cnt; keep Employee_ID Error_Type Month Count; run; /* 输出验证结果 */ proc print data=result noobs; run;
结果验证
运行代码后输出的result数据集的Count字段和提供的样例完全匹配,符合规则要求。
内容的提问来源于stack exchange,提问作者Putul
相关产品推荐
相关产品推荐

