SAS宏中能否嵌套%sysfunc函数?变量名转换问题求解
SAS变量名替换与宏代码生成问题解决
问题场景
现有以下SAS数据集存储待处理的变量名:
Data variables; input variable $; datalines; Exkl_UtgUtl_Flyg Exkl_UtgUtl_Tag Exkl_UtgUtl_Farja Exkl_UtgUtl_Hyrbil Exkl_UtgUtl_Bo Exkl_UtgUtl_Aktiv Exkl_UtgUtl_Annat ; run;
需要将Exkl_UtgUtl_Flyg这类变量关联到UtgUtl_FlygSSEK_Pers和UtgUtl_FlygSSEK_PPmedel格式的变量,实现逻辑:当Exkl_XXX=1且XXXSSEK_Pers缺失时,用XXXSSEK_PPmedel赋值给它。
尝试的解决方案及问题
原尝试通过宏实现,但嵌套的TRANWRD函数未生效,生成的代码未移除Exkl_前缀:
原宏代码
%macro imputera_saknad_utgift(variabel); DATA IBIS3_5; SET IBIS3_5; if &variabel=1 and %sysfunc(cats(%qsysfunc(TRANWRD(&variabel,'Exkl_','')),SSEK_Pers))=. then %sysfunc(cats(%qsysfunc(TRANWRD(&variabel,'Exkl_','')),SSEK_Pers))=%sysfunc(cats(%qsysfunc(TRANWRD(&variabel,'Exkl_','')),SSEK_PPmedel)); RUN; %mend imputera_saknad_utgift;
执行代码
data _null_; set variabler2; call execute(cats('%imputera_saknad_utgift(',utgifter_inte_missing,')')); run;
生成的错误代码
DATA IBIS3_5; SET IBIS3_5; if Exkl_UtgUtl_Bo=1 and Exkl_UtgUtl_BoSSEK_Pers=. then Exkl_UtgUtl_BoSSEK_Pers=Exkl_UtgUtl_BoSSEK_PPmedel;
期望生成的正确代码
DATA IBIS3_5; SET IBIS3_5; if Exkl_UtgUtl_Bo=1 and UtgUtl_BoSSEK_Pers=. then UtgUtl_BoSSEK_Pers=UtgUtl_BoSSEK_PPmedel;
两种可行解决方法
方法1:修改宏,提前存储处理后的变量名
通过%let将移除前缀后的变量名存为临时宏变量,避免宏函数嵌套的执行顺序问题:
%macro imputera_saknad_utgift(variabel); /* 移除Exkl_前缀,存储为临时宏变量 */ %let base_var = %sysfunc(tranwrd(&variabel, Exkl_, )); DATA IBIS3_5; SET IBIS3_5; if &variabel=1 and &base_var.SSEK_Pers=. then &base_var.SSEK_Pers = &base_var.SSEK_PPmedel; RUN; %mend imputera_saknad_utgift;
执行原call execute代码即可生成正确的赋值逻辑,宏变量&base_var会被替换为移除前缀后的字符串。
方法2:直接在DATA步中拼接代码
跳过宏定义,直接在call execute所在的DATA步完成字符串处理与代码拼接,更直观:
data _null_; set variabler2; /* 移除Exkl_前缀 */ length base_var $32; base_var = tranwrd(utgifter_inte_missing, 'Exkl_', ''); /* 拼接完整的SAS代码并执行 */ call execute(cats( 'DATA IBIS3_5; SET IBIS3_5; ', 'if ', utgifter_inte_missing, '=1 and ', base_var, 'SSEK_Pers=. then ', base_var, 'SSEK_Pers=', base_var, 'SSEK_PPmedel; RUN;' )); run;
该方法利用DATA步的tranwrd函数直接处理变量名字符串,无需依赖宏函数嵌套,代码逻辑更清晰。
内容的提问来源于stack exchange,提问作者Magnus
相关产品推荐
相关产品推荐

