如何用SAS按ID统计15分钟时间窗内的Occurrence?
按ID分组划分15分钟内事件Occurrence的SAS解决方案
不需要宏代码,用基础的数据步+BY组处理就能搞定,步骤如下:
1. 预处理:确保时间格式正确并排序
首先要把你的TIMESTAMP转换成SAS能识别的日期时间格式(如果原始是字符型的话),然后按ID和TIMESTAMP升序排序,这是BY组处理的前提:
/* 转换字符型时间为SAS日期时间格式(如果你的TIMESTAMP已经是datetime类型可跳过这步) */ data have_clean; set have; timestamp_dt = input(timestamp, mmddyy10. + time5.); /* 根据你的原始格式调整输入格式 */ format timestamp_dt datetime20.; run; /* 按ID和时间排序 */ proc sort data=have_clean; by id timestamp_dt; run;
2. 数据步划分Occurrence
用BY组处理每个ID,通过保留变量跟踪当前事件的起始时间,判断当前时间与起始时间的差值是否超过15分钟(即900秒),超过则开启新的Occurrence:
data want; set have_clean; by id; /* 每个ID的第一条记录初始化 */ if first.id then do; occurrence = 1; start_time = timestamp_dt; end; else do; /* 计算当前时间与当前事件起始时间的秒差 */ time_diff = timestamp_dt - start_time; if time_diff > 900 then do; /* 15分钟=900秒 */ occurrence + 1; start_time = timestamp_dt; /* 更新当前事件的起始时间 */ end; /* 否则occurrence保持不变 */ end; /* 保留原始变量和新生成的occurrence */ keep id timestamp timestamp_dt occurrence; run;
代码解释
by id:按ID分组处理,first.id标记每个ID的第一条记录start_time:保留变量,存储当前Occurrence的起始时间,每次开启新事件时更新time_diff:计算当前时间与起始时间的秒差,超过900秒(15分钟)就递增Occurrence计数- 最终输出的
occurrence列会给每个连续15分钟内的事件标记同一个序号,和你示例中的需求一致(示例里只在起始行标1,实际代码会给同组所有行都标对应的序号)
如果需要和示例一样只在每个Occurrence的第一行显示1,其他行空着,可以修改数据步:
data want_display; set want; by id occurrence; if first.occurrence then display_occurrence = 1; else display_occurrence = .; drop occurrence; rename display_occurrence = occurrence; run;
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

