如何使用宏变量存储的变量列表定义SAS数组?
SAS宏变量与数组遍历问题
我有15个相似变量,需要通过循环将特定值重编码为空。因为后续会添加更多变量,所以用宏实现。我已经创建了存储变量列表和变量数量的宏变量,但定义数组时遇到问题:现有代码仅能遍历&varlist1,无法覆盖其余14个变量(varlist2至varlist15),希望在不破坏现有代码逻辑的前提下,找到扩展至全变量列表的方法。
目标变量列表
NEW_CREWSTATE1A NEW_EquFailText NEW_ExpMedNotList NEW_NARRATIVEDISTRESS NEW_NarrativeRecovery NEW_NarrativeSearch NEW_OthEquText NEW_PersReqMedTxt NEW_ProbEnct NEW_Recommend NEW_RescueSwimProbText NEW_RescuerProb NEW_SRUConfigTxt NEW_equimalissue new_MedDiffText
现有代码
proc sql noprint; select count(name) into :numVar from sashelp.vcolumn where upcase(LIBname)="STAGING" and UPCASE(memname)="RESC_NARRATIVEMERGE" and UPCASE(name) like 'NEW_%'; quit; %put &numVar; proc sql noprint; select distinct(name) into :varlist1- from sashelp.vcolumn where upcase(LIBname)="STAGING" and UPCASE(memname)="RESC_NARRATIVEMERGE" and UPCASE(name) like 'NEW_%'; quit; data staging.RESC_NARRATIVEMERGE2; set staging.RESC_NARRATIVEMERGE; array narrative_array {*} &varlist1. ; do i=1 to dim(narrative_array); if strip(narrative_array{i})='N/A' then narrative_array{i}=''; if strip(narrative_array{i})='N/A.' then narrative_array{i}=''; if strip(narrative_array{i})='NA' then narrative_array{i}=''; if strip(narrative_array{i})='NONE' then narrative_array{i}=''; if strip(narrative_array{i})='NONE NOTED' then narrative_array{i}=''; if strip(narrative_array{i})='NONE EXPERIENCED' then narrative_array{i}=''; if strip(narrative_array{i})='NONE TO REPORT' then narrative_array{i}=''; if strip(narrative_array{i})='NONE.' then narrative_array{i}=''; if strip(narrative_array{i})='NOT APPLICABLE' then narrative_array{i}=''; end; run;
解决方案
问题根源是SQL语句中into :varlist1-会生成多个独立宏变量(&varlist1到&varlist15),但现有代码仅引用了第一个宏变量,导致数组只包含单个变量。以下两种方法可以快速修复:
方法1:生成单个宏变量存储全量变量列表
修改第二个proc sql语句,将所有变量存入一个宏变量(用separated by ' '指定分隔符):
proc sql noprint; select distinct(name) into :varlist separated by ' ' from sashelp.vcolumn where upcase(LIBname)="STAGING" and UPCASE(memname)="RESC_NARRATIVEMERGE" and UPCASE(name) like 'NEW_%'; quit;
然后在数组定义中直接引用这个宏变量:
array narrative_array {*} &varlist. ;
方法2:保留多宏变量,通过宏循环拼接列表
如果要保留原有的多宏变量生成逻辑,可以编写一个简单宏来遍历所有宏变量并拼接成完整列表:
%macro get_varlist(); %do i=1 %to &numVar.; &&varlist&i. %end; %mend;
数组定义改为调用该宏:
array narrative_array {*} %get_varlist() ;
额外优化:简化条件判断逻辑
原代码中多个重复的if语句可以简化,通过定义一个存储替换值的临时数组,用in操作批量判断:
data staging.RESC_NARRATIVEMERGE2; set staging.RESC_NARRATIVEMERGE; array narrative_array {*} &varlist. ; array replace_vals [9] $20 ('N/A', 'N/A.', 'NA', 'NONE', 'NONE NOTED', 'NONE EXPERIENCED', 'NONE TO REPORT', 'NONE.', 'NOT APPLICABLE'); do i=1 to dim(narrative_array); if strip(narrative_array{i}) in replace_vals then narrative_array{i}=''; end; run;
内容的提问来源于stack exchange,提问作者Epiwatson7
相关产品推荐
相关产品推荐

