SAS PROC SQL如何实现5年滚动日期窗口的分组去重计数
5年滚动窗口去重计数问题解答
将原180天窗口判断条件修改为h2.year BETWEEN h.year-5 AND h.year,无法得到正确的近5年去重计数结果,核心问题有两点:
- 窗口长度不符合统计要求:该条件实际覆盖6个自然年,而非5年。例如当前行年份为2005时,匹配范围是2000-2005共6年,最终统计值会偏高。如果你的统计口径是「包含当前年在内的近5个自然年」,条件应改为
h2.year BETWEEN h.year-4 AND h.year;如果是「不包含当前年的过去5年」,则改为h2.year BETWEEN h.year-5 AND h.year-1,可根据实际业务口径调整。 - 年份判断逻辑仅适用于年度粒度数据:如果你的原始数据是精确到日的日期维度数据,直接用年份差做判断会产生统计误差。例如当前记录日期为2025年1月1日,2020年12月31日的记录按年份差算满足间隔5年的要求,但实际两个日期间隔已超过5年,会被错误纳入统计范围。
针对你提供的年度粒度测试数据集,可参考以下代码实现正确统计:
data have; input permno year Cand_ID$; datalines; 1 2000 1 1 2001 2 1 2002 3 1 2003 1 1 2004 3 1 2005 1 2 2000 1 2 2001 3 2 2002 1 2 2003 2 2 2004 2 2 2005 2 2 2006 1 2 2007 1 3 2001 3 3 2002 3 3 2003 3 3 2004 1 3 2005 1 ; run; /* 统计口径:包含当前年的近5个自然年,按permno分组统计Cand_ID去重数量 */ proc sql; create table want as select h.permno, h.year, count(distinct h2.Cand_ID) as distinct_cand_cnt format=best. from have h left join have h2 on h.permno = h2.permno and h2.year between h.year-4 and h.year group by h.permno, h.year order by h.permno, h.year; quit;
结果验证参考(以测试集中permno=1的分组为例):
- 2000年:窗口覆盖1996-2000,仅出现Cand_ID=1,计数为1
- 2001年:窗口覆盖1997-2001,出现Cand_ID 1、2,计数为2
- 2002-2005年:窗口覆盖范围内均包含Cand_ID 1、2、3,计数均为3
如果使用最初写的h.year-5判断条件,在存在早于当前年5年以上的历史数据时,计数结果会比实际值偏高。
如果你的原始数据是日粒度的日期数据,不要用年份字段做窗口判断,直接使用SAS日期函数计算精确窗口即可,例如写为h2.date between intnx('year', h.date, -5, 'same') and h.date,就能得到精确到天的5年滚动窗口,避免年份差判断带来的统计误差。
内容的提问来源于stack exchange,提问作者Ankita Damani
相关产品推荐
相关产品推荐

