SAS中字符变量与搜索词列表匹配生成匹配指示变量问题咨询
问题原因
- 宏生成的
index(team,&next_name)语法错误:&next_name是字符串类型的搜索词,需要加引号包裹,否则SAS会将其识别为变量名而非字符串常量,匹配不到对应变量就默认值为空,导致index函数始终返回0,看起来就像没效果。 - 循环逻辑错误:每次循环都直接覆盖
indicator的值,最终只会保留最后一个搜索词的匹配结果,无法实现“只要有任意一个搜索词匹配就标记为1”的需求。 - 宏定义完成后没有执行调用语句,所以宏内逻辑根本没有运行,自然不会生成结果也不会报错。
修正后的可运行代码
方案1:沿用原有宏遍历逻辑修正
* 生成搜索词数据集; data terms; set sashelp.baseball (obs=5); search_term = substr(team,1,3); keep search_term; run; * 生成待匹配主数据集,先初始化指示变量为0; data test; set sashelp.baseball; indicator = 0; run; %macro search; %local i name_list next_name; * 导出搜索词到宏变量; proc SQL noprint; select distinct search_term into :name_list separated by ' ' from work.terms; quit; %let i=1; %do %while (%scan(&name_list, &i) ne ); %let next_name = %scan(&name_list, &i); * 匹配到任意搜索词就把indicator设为1,保留之前已匹配的结果; data test; set test; if index(team,"&next_name")>0 then indicator=1; run; %let i = %eval(&i + 1); %end; %mend; * 调用宏执行匹配; %search;
方案2:更高效的正则匹配方案(无需循环)
搜索词数量较多时,该方案性能远高于循环重写数据集:
* 生成搜索词数据集; data terms; set sashelp.baseball (obs=5); search_term = substr(team,1,3); keep search_term; run; * 把所有搜索词拼接成正则匹配规则,|代表“或”逻辑; proc sql noprint; select catx('|', search_term) into :match_pattern from terms; quit; * 一次性完成所有搜索词的匹配判断; data test; set sashelp.baseball; indicator = (prxmatch("/&match_pattern./", team) > 0); run;
内容的提问来源于stack exchange,提问作者Menzer
相关产品推荐
相关产品推荐

