SAS中按ID分组填充同组变量非缺失值的实现方法
SAS按组填充非缺失值实现方案
需求逻辑:按ID字段分组,若同组内目标变量var存在非缺失观测,则将该值填充至同组var的所有行;若同组var全为缺失,则保持原缺失值不变。
方法1:PROC SQL汇总匹配法(逻辑直白易调试)
无需复杂循环,适合新手,代码可读性强:
/* 提前按ID排序(若原数据集已按ID排序可跳过此步) */ proc sort data=have; by ID; run; /* 提取每个ID组对应的非缺失填充值,全缺失的ID不会生成记录 */ proc sql noprint; create table tmp_fill as select distinct ID, var as fill_val from have where var is not null; quit; /* 将填充值匹配回原表,仅对存在非缺失值的组执行覆盖 */ data want; merge have tmp_fill(in=has_fill); by ID; if has_fill then var = fill_val; drop fill_val; run;
方法2:双DOW循环法(无中间表,大数据量效率更高)
单数据步完成组内遍历+填充,适合千万行级别的大表:
/* 提前按ID排序(若原数据集已按ID排序可跳过此步) */ proc sort data=have; by ID; run; data want; length fill_val 8; /* 定义填充值变量类型,和原var保持一致 */ /* 第一遍遍历当前ID组所有行,获取组内非缺失填充值 */ do until(last.ID); set have; by ID; /* 若需取组内第一个非缺失值,改为 if missing(fill_val) and not missing(var) then fill_val=var; */ /* 若需取组内最大值,改为 fill_val = max(fill_val, var); */ if not missing(var) then fill_val = var; end; /* 第二遍遍历当前ID组所有行,执行填充后输出 */ do until(last.ID); set have; by ID; if not missing(fill_val) then var = fill_val; output; end; drop fill_val; run;
结果验证
使用提供的样例数据集运行上述任意一段代码,均可得到期望输出:
输入数据集Have样例:
ID var 1 . 1 1 1 1 1 1 1 . 1 . 1 . 2 . 2 . 2 . 2 . 2 . 3 . 3 . 3 1 3 . 4 . 4 . 4 . 4 .输出数据集Want样例:
ID var 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 . 2 . 2 . 2 . 2 . 3 1 3 1 3 1 3 1 4 . 4 . 4 . 4 .
注意事项
如果同组内var存在多个不同的非缺失值,可根据业务需求调整fill_val的赋值规则,默认逻辑取组内遍历到的最后一个非缺失值。
内容的提问来源于stack exchange,提问作者SAS_newby
相关产品推荐
相关产品推荐

