在SAS中生成enrol_flag变量:按ID分组,enrol为0后永久置0
问题:基于SAS生成enrol_flag变量
现有按ID和Date排序的SAS数据集,包含ID、Date、enrol三个变量。需生成新数据集并新增enrol_flag变量,规则如下:
- 当
enrol为1且该ID尚未出现过enrol=0时,enrol_flag为1; - 一旦该ID出现过
enrol=0,之后所有行的enrol_flag均为0。
原始数据集
ID Date enrol 1 01JAN21 0 1 01FEB21 1 1 01MAR21 1 1 01APR21 1 1 01MAY21 0 1 01JUN21 0 1 01JUL21 1 1 01AUG21 1 2 01JAN21 1 2 01FEB21 1 2 01MAR21 1 2 01APR21 1 2 01MAY21 1 2 01JUN21 0 2 01JUL21 0 2 01AUG21 0 3 01FEB21 0 3 01MAR21 0 3 01APR21 0 3 01MAY21 0 3 01JUN21 0 3 01JUL21 1
期望输出
ID Date enrol enrol_flag 1 01JAN21 0 0 1 01FEB21 1 1 1 01MAR21 1 1 1 01APR21 1 1 1 01MAY21 0 0 1 01JUN21 0 0 1 01JUL21 1 0 1 01AUG21 1 0 2 01JAN21 1 1 2 01FEB21 1 1 2 01MAR21 1 1 2 01APR21 1 1 2 01MAY21 1 1 2 01JUN21 0 0 2 01JUL21 0 0 2 01AUG21 0 0 3 01FEB21 0 0 3 01MAR21 0 0 3 01APR21 0 0 3 01MAY21 0 0 3 01JUN21 0 0 3 01JUL21 1 1
SAS解决方案
利用SAS的BY组处理和retain变量实现需求,代码如下:
data want; set have; by ID; retain has_zero 0; /* 每个ID的第一行重置标记变量 */ if first.ID then has_zero = 0; /* 根据标记变量判断enrol_flag的值 */ if has_zero then do; enrol_flag = 0; end; else do; if enrol = 1 then enrol_flag = 1; else do; enrol_flag = 0; has_zero = 1; /* 标记该ID已出现过enrol=0 */ end; end; run;
代码说明
by ID:按ID分组处理,确保每个ID的逻辑独立;retain has_zero 0:保留has_zero变量的值跨观测传递,初始值设为0(表示未出现过enrol=0);first.ID:当处理到每个ID的第一行时,重置has_zero为0,避免不同ID的标记互相干扰;- 逻辑判断:如果
has_zero为1(已出现过0),则enrol_flag直接设为0;否则根据当前enrol的值设置enrol_flag,若当前enrol=0则将has_zero设为1,后续行均按0处理。
内容的提问来源于stack exchange,提问作者Abhijeet Rajpurohit
相关产品推荐
相关产品推荐

