SAS 9.4:无需Merge或Proc SQL,如何跨数据集查找引用值
在SAS数据步中实现邮编存在性验证检查
需求背景
需要在现有错误检查数据步中新增验证:判断postcode是否存在于包含270万条记录的有效邮编列表postcode_list中,不存在则标记为error_type3=1,最终拆分错误/无错误记录。
现有代码
Data error_check; set Data; If (check 1) then error_type1 = 1; else error_type1 = 0; If (check 2) then error_type2 = 1; else error_type2 = 0; run; Data error no_error; set error_check; if error_type1 = 1 or error_type2 = 1 then output error; else output no_error; run;
解决方案:两种纯数据步实现方式
方法1:自定义格式(适合大体积邮编列表)
通过将有效邮编转换为自定义格式,在数据步中快速判断邮编有效性,效率稳定:
/* 生成有效邮编的格式定义参数 */ proc sql noprint; select distinct quote(trim(post_code)) into :valid_postcodes separated by ' ' from postcode_list; quit; /* 创建自定义邮编验证格式 */ proc format; value $valid_postcode &valid_postcodes = 'VALID' other = 'INVALID'; run; /* 原有数据步中新增邮编检查 */ Data error_check; set Data; If (check 1) then error_type1 = 1; else error_type1 = 0; If (check 2) then error_type2 = 1; else error_type2 = 0; /* 新增:判断邮编是否无效,无效则标记error_type3=1 */ error_type3 = (put(postcode, $valid_postcode.) = 'INVALID'); run; /* 拆分错误/无错误记录 */ Data error no_error; set error_check; if error_type1 = 1 or error_type2 = 1 or error_type3 = 1 then output error; else output no_error; run;
方法2:哈希表(内存充足时效率最优)
直接在数据步中加载哈希表,实时查询邮编是否存在,查询速度接近O(1):
Data error_check; set Data; /* 仅在第一次循环时初始化哈希表 */ if _n_ = 1 then do; declare hash postcode_hash(dataset:'postcode_list'); postcode_hash.defineKey('post_code'); /* 定义哈希表的键为有效邮编字段 */ postcode_hash.defineDone(); call missing(post_code); /* 清空临时变量 */ end; If (check 1) then error_type1 = 1; else error_type1 = 0; If (check 2) then error_type2 = 1; else error_type2 = 0; /* 新增:查询哈希表,返回非0表示未找到,标记错误 */ error_type3 = (postcode_hash.find(key:postcode) ne 0); run; /* 拆分记录 */ Data error no_error; set error_check; if error_type1 = 1 or error_type2 = 1 or error_type3 = 1 then output error; else output no_error; run;
说明
- 哈希表方法:适合内存足够的场景,270万条邮编记录占用内存不大,查询速度最快,完全在数据步内完成,无需依赖Proc SQL。
- 自定义格式方法:兼容性更好,即使内存有限也能稳定运行,格式生成后可重复使用。
内容的提问来源于stack exchange,提问作者Rara_Barnes
相关产品推荐
相关产品推荐

