在SAS的PROC SQL中去除字符串最后一词后用COMPGED比较姓名
SAS PROC SQL解决方案:排除最后一个词后比较姓名并处理特殊字符差异
需求说明
- 从包含
oldname和newname的SAS数据集中,排除每个姓名的最后一个词(适配已婚改姓场景)后进行姓名比较 - 处理如
Jose与José的细微字符差异,使用COMPGED函数计算差异得分 - 要求在PROC SQL框架内实现
错误代码分析
原代码的核心问题是SCAN函数的第三个参数应为修饰符,而非提取词的数量,导致语法逻辑失效:
proc sql; create table want as select *, compged(catx(' ', scan(oldname, 1, countw(oldname)-1)), catx(' ', scan(newname, 1, countw(newname)-1))) as GED from have;
正确PROC SQL实现方案
核心思路
- 提取排除最后一个词的姓名部分:通过反向查找最后一个空格的位置,截取除最后一个词外的内容,同时兼容单词姓名的边界情况
- 统一字符编码:转换带重音的字符为普通字符,消除
Jose/José这类差异 - 计算COMPGED差异得分:基于处理后的字符串计算广义编辑距离
完整代码:
proc sql; create table want as select oldname, newname, /* 提取oldname除最后一个词外的内容 */ case when countw(oldname) > 1 then substr(oldname, 1, find(oldname, ' ', -1, 'i') - 1) else oldname end as oldname_no_last, /* 提取newname除最后一个词外的内容 */ case when countw(newname) > 1 then substr(newname, 1, find(newname, ' ', -1, 'i') - 1) else newname end as newname_no_last, /* 转换重音字符后计算COMPGED差异得分 */ compged( translate(calculated oldname_no_last, 'AEIOUaeiou', 'ÁÉÍÓÚáéíóú'), translate(calculated newname_no_last, 'AEIOUaeiou', 'ÁÉÍÓÚáéíóú') ) as GED from have; quit;
代码细节说明
countw():统计姓名中的单词数量,用于判断是否需要执行截取操作find(oldname, ' ', -1, 'i'):反向查找最后一个空格的位置,'i'修饰符用于忽略大小写(可选)TRANSLATE():将带重音的元音字符转换为普通元音,消除字符编码差异COMPGED():计算两个字符串的广义编辑距离,得分越低表示字符串相似度越高
内容的提问来源于stack exchange,提问作者LuizZ
相关产品推荐
相关产品推荐

