You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于SAS生成多月度标识:适配连续非零薪资区间需求

SAS滚动15个月周期的薪资标识生成方案

需求拆解

针对每个ID的滚动15个月窗口,完成以下逻辑:

  • 筛选出窗口前3个月薪资全为0、后3个月薪资全为0的有效窗口
  • 有效窗口的中间9个月中,仅将从第一个非零月起至第一个零月前的连续非零区间标记为1,其余月份(包括零月及后续非零月)标记为0
  • 最终输出与原薪资变量一一对应的96个月度标识变量,不符合条件的月份统一标0

实现步骤与SAS代码

假设原始数据为宽表结构,每行对应一个ID,包含96个薪资变量(命名规则:salary_YYYYMM,如salary_201501至salary_202212)。以下代码通过「长表处理+滚动窗口判断+宽表输出」的流程实现需求:

1. 将宽表转换为长表

先把横向的薪资变量转为纵向的月度记录,方便滚动窗口计算:

/* 转换长表 */
data salary_long;
    set original_salary_data;
    length month $6.;
    array salary_arr[96] salary_201501-salary_202212; /* 替换为实际的薪资变量范围 */
    array month_list[96] $6. _temporary_ ('201501','201502',...,'202212'); /* 按顺序生成96个月份字符串 */
    
    do i=1 to 96;
        month = month_list[i];
        salary = salary_arr[i];
        output;
    end;
    drop i salary_201501-salary_202212;
run;

/* 按ID和月份排序 */
proc sort data=salary_long;
    by id month;
run;

2. 滚动窗口判断与标识生成

在长表中,通过LAG和LEAD函数获取滚动15个月窗口内的薪资数据,判断有效窗口并生成标识:

data flag_long;
    set salary_long;
    by id;
    retain window_active;
    
    /* 定义滚动窗口的前后3个月、中间9个月薪资 */
    lag1 = lag3(salary); /* 窗口第1个月薪资 */
    lag2 = lag2(salary); /* 窗口第2个月薪资 */
    lag3 = lag1(salary); /* 窗口第3个月薪资 */
    lead1 = lead1(salary); /* 窗口第13个月薪资 */
    lead2 = lead2(salary); /* 窗口第14个月薪资 */
    lead3 = lead3(salary); /* 窗口第15个月薪资 */
    
    /* 判断当前窗口是否为有效窗口(前3全0、后3全0) */
    if first.id then window_active = 0;
    if (lag1=0 and lag2=0 and lag3=0 and lead1=0 and lead2=0 and lead3=0) then do;
        window_active = 1;
        /* 追踪中间9个月的连续非零区间 */
        retain consecutive_nonzero;
        if first.id then consecutive_nonzero = 0;
        
        if salary > 0 and not missing(salary) then do;
            if consecutive_nonzero = 0 then consecutive_nonzero = 1;
            flag = 1;
        end;
        else do;
            consecutive_nonzero = 0;
            flag = 0;
        end;
    end;
    else do;
        /* 非有效窗口或已中断连续区间,标记为0 */
        window_active = 0;
        consecutive_nonzero = 0;
        flag = 0;
    end;
    
    drop lag1-lag3 lead1-lead3;
run;

3. 将长表转回宽表,生成96个月度标识变量

把处理后的长表转回宽表,得到与原薪资变量一一对应的标识变量:

proc transpose data=flag_long out=flag_wide(drop=_name_ _label_);
    by id;
    id month;
    var flag;
run;

/* 重命名标识变量为统一格式(如flag_YYYYMM) */
data final_flag_data;
    set flag_wide;
    rename _201501=flag_201501 _201502=flag_201502 ... _202212=flag_202212; /* 对应96个月份 */
run;

示例验证

针对题目中的两个示例:

  1. 周期薪资序列:0,0,0,20,40,50,0,0,0,0,0,0,0,0,0
    • 有效窗口判断:前3月全0、后3月全0,符合条件
    • 中间9个月连续非零区间为前3个月,对应标识:0,0,0,1,1,1,0,0,0,0,0,0,0,0,0
  2. 周期薪资序列:0,0,0,20,50,30,0,20,0,0,0,0,0,0,0
    • 有效窗口判断:前3月全0、后3月全0,符合条件
    • 中间9个月中第4个月份为0,终止连续区间,对应标识:0,0,0,1,1,1,0,0,0,0,0,0,0,0,0

以上代码可准确实现该逻辑,需注意根据实际数据的薪资变量命名、月份范围调整数组和重命名语句。

内容的提问来源于stack exchange,提问作者unluckyforsome

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 18:54:53